├── CDFSampleApp
├── CDFSampleApp
│ ├── Assets
│ │ ├── StoreLogo.png
│ │ ├── SplashScreen.scale-200.png
│ │ ├── LockScreenLogo.scale-200.png
│ │ ├── Square44x44Logo.scale-200.png
│ │ ├── Wide310x150Logo.scale-200.png
│ │ ├── Square150x150Logo.scale-200.png
│ │ └── Square44x44Logo.targetsize-24_altform-unplated.png
│ ├── CDFSampleApp_Ashish_TemporaryKey.pfx
│ ├── ApplicationInsights.config
│ ├── App.xaml
│ ├── project.json
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Default.rd.xml
│ ├── MainPage.xaml
│ ├── Package.appxmanifest
│ ├── App.xaml.cs
│ ├── CDFSampleApp.csproj
│ └── MainPage.xaml.cs
├── Tasks
│ ├── project.json
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Tasks.csproj
│ └── myBGTask.cs
├── README.md
└── CDFSampleApp.sln
├── LICENSE
├── README.md
├── .gitattributes
├── SECURITY.md
└── .gitignore
/CDFSampleApp/CDFSampleApp/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/companion-device-framework/HEAD/CDFSampleApp/CDFSampleApp/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/companion-device-framework/HEAD/CDFSampleApp/CDFSampleApp/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/companion-device-framework/HEAD/CDFSampleApp/CDFSampleApp/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/companion-device-framework/HEAD/CDFSampleApp/CDFSampleApp/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/companion-device-framework/HEAD/CDFSampleApp/CDFSampleApp/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/CDFSampleApp_Ashish_TemporaryKey.pfx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/companion-device-framework/HEAD/CDFSampleApp/CDFSampleApp/CDFSampleApp_Ashish_TemporaryKey.pfx
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/companion-device-framework/HEAD/CDFSampleApp/CDFSampleApp/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/ApplicationInsights.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/companion-device-framework/HEAD/CDFSampleApp/CDFSampleApp/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CDFSampleApp/Tasks/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
4 | },
5 | "frameworks": {
6 | "uap10.0": {}
7 | },
8 | "runtimes": {
9 | "win10-arm": {},
10 | "win10-arm-aot": {},
11 | "win10-x86": {},
12 | "win10-x86-aot": {},
13 | "win10-x64": {},
14 | "win10-x64-aot": {}
15 | }
16 | }
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.ApplicationInsights": "1.0.0",
4 | "Microsoft.ApplicationInsights.PersistenceChannel": "1.0.0",
5 | "Microsoft.ApplicationInsights.WindowsApps": "1.0.0",
6 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
7 | },
8 | "frameworks": {
9 | "uap10.0": {}
10 | },
11 | "runtimes": {
12 | "win10-arm": {},
13 | "win10-arm-aot": {},
14 | "win10-x86": {},
15 | "win10-x86-aot": {},
16 | "win10-x64": {},
17 | "win10-x64-aot": {}
18 | }
19 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Microsoft Corporation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/CDFSampleApp/Tasks/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Tasks")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Tasks")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CDFSampleApp_Ashish")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("CDFSampleApp_Ashish")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/CDFSampleApp/README.md:
--------------------------------------------------------------------------------
1 | # CDF Sample App
2 |
3 | The sample demonstrates how you can use the CDF APIs to build a UWP app to unlock a Windows PC using a companion device. For the sake of simplicity and ease, the sample does a lot of operations (like key generation, HMAC operations, etc.) in this sample itself on the PC i.e., making the PC itself as the companion device. When you implement your own UWP app, please use a transport (like BT, NFC, etc.) to talk to a companion device and have the companion device do some of these operations especially the key generaiton, key storage and HMAC operation.
4 |
5 | In the Sample
6 | -------------
7 | The sample has two components - foreground and background task.
8 |
9 | 1. The foreground component registers the background task and registers the companion device to be used for Windows unlock.
10 |
11 | 2. The background component does the actual auth operation and hence, performs the unlock.
12 |
13 | Before using the sample
14 | -----------------------
15 | When you use the sample code, please do the following:
16 |
17 | 1. Setup PIN auth/PIN based logon on your PC
18 | You should use Settings app-> Accounts -> Sign-in Options to set the PIN for your PC.
19 | If for some reason, PIN based logon is disabled on your PC, you may be able to either use gpedit.msc or set reg key. This setting can be enabled by creating the AllowDomainPINLogon REG_DWORD value under the HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System Registry key and setting it to 1.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Windows Hello Unlock using Companion Devices
2 |
3 | Welcome to the Companion Device Framework Github Repostiory.
4 |
5 | ## Introduction
6 |
7 | This repo hosts Windows UWP sample code to illustrate the use of Companion Device Framework (CDF), a new feature in Windows 10, enabling developers to build UWP apps to unlock Windows 10 PCs. A companion device is a device that can act in conjunction with your Windows 10 desktop to enhance the user authentication experience. Using the Companion Device Framework, a companion device can provide a rich experience for Microsoft Passport even when Windows Hello is not available (e.g., if the Windows 10 desktop lacks a camera for face authentication or fingerprint reader device, for example).
8 |
9 | ## Requirements
10 |
11 | - Windows 10 Anniversary Update Enterprise/Professional edition (Build 10.0.14393 or later)
12 | - Visual Studio 2015
13 | - [Windows Software Development Kit (SDK) for Windows 10] (https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
14 |
15 | ## Requesting capabilities for Store Submissions of your CDF UWP App
16 |
17 | You are free to use the code sample to create your own CDF UWP app to unlock Windows PCs. To submit your app to the Store, you would need permissions to use the secondaryAuthenticationFactor restricted capability. For the same, please mail Companion Device Framework Onboarding .
18 |
19 | ## Feedback
20 |
21 | - File a bug in [GitHub Issues] (https://github.com/Microsoft/companion-device-framework/issues)
22 | - For requesting new features, please mail Companion Device Framework Onboarding .
23 |
24 | ## Additional resources
25 |
26 | - [Introduction] (https://msdn.microsoft.com/en-us/windows/uwp/security/companion-device-unlock) to Windows Hello Companion Device Framework
27 | - [Video preview] (https://channel9.msdn.com/events/build/2016/p491) of Windows Hello Companion Device Framework
28 |
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | CDFSampleApp_Ashish
7 | ashishj
8 | Assets\StoreLogo.png
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CDFSampleApp", "CDFSampleApp\CDFSampleApp.csproj", "{9FDD0FF8-7487-428F-8325-D247F2CD3923}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tasks", "Tasks\Tasks.csproj", "{CEA8E664-3E8B-4188-808B-BA20B2BE278E}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|ARM = Debug|ARM
14 | Debug|x64 = Debug|x64
15 | Debug|x86 = Debug|x86
16 | Release|Any CPU = Release|Any CPU
17 | Release|ARM = Release|ARM
18 | Release|x64 = Release|x64
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|Any CPU.ActiveCfg = Debug|x86
23 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|ARM.ActiveCfg = Debug|ARM
24 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|ARM.Build.0 = Debug|ARM
25 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|ARM.Deploy.0 = Debug|ARM
26 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|x64.ActiveCfg = Debug|x64
27 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|x64.Build.0 = Debug|x64
28 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|x64.Deploy.0 = Debug|x64
29 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|x86.ActiveCfg = Debug|x86
30 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|x86.Build.0 = Debug|x86
31 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Debug|x86.Deploy.0 = Debug|x86
32 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|Any CPU.ActiveCfg = Release|x86
33 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|ARM.ActiveCfg = Release|ARM
34 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|ARM.Build.0 = Release|ARM
35 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|ARM.Deploy.0 = Release|ARM
36 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|x64.ActiveCfg = Release|x64
37 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|x64.Build.0 = Release|x64
38 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|x64.Deploy.0 = Release|x64
39 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|x86.ActiveCfg = Release|x86
40 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|x86.Build.0 = Release|x86
41 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}.Release|x86.Deploy.0 = Release|x86
42 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Debug|Any CPU.Build.0 = Debug|Any CPU
44 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Debug|ARM.ActiveCfg = Debug|ARM
45 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Debug|ARM.Build.0 = Debug|ARM
46 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Debug|x64.ActiveCfg = Debug|x64
47 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Debug|x64.Build.0 = Debug|x64
48 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Debug|x86.ActiveCfg = Debug|x86
49 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Debug|x86.Build.0 = Debug|x86
50 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Release|Any CPU.Build.0 = Release|Any CPU
52 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Release|ARM.ActiveCfg = Release|ARM
53 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Release|ARM.Build.0 = Release|ARM
54 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Release|x64.ActiveCfg = Release|x64
55 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Release|x64.Build.0 = Release|x64
56 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Release|x86.ActiveCfg = Release|x86
57 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}.Release|x86.Build.0 = Release|x86
58 | EndGlobalSection
59 | GlobalSection(SolutionProperties) = preSolution
60 | HideSolutionNode = FALSE
61 | EndGlobalSection
62 | EndGlobal
63 |
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 |
18 | namespace CDFSampleApp_Ashish
19 | {
20 | ///
21 | /// Provides application-specific behavior to supplement the default Application class.
22 | ///
23 | sealed partial class App : Application
24 | {
25 | ///
26 | /// Initializes the singleton application object. This is the first line of authored code
27 | /// executed, and as such is the logical equivalent of main() or WinMain().
28 | ///
29 | public App()
30 | {
31 | Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
32 | Microsoft.ApplicationInsights.WindowsCollectors.Metadata |
33 | Microsoft.ApplicationInsights.WindowsCollectors.Session);
34 | this.InitializeComponent();
35 | this.Suspending += OnSuspending;
36 | }
37 |
38 | ///
39 | /// Invoked when the application is launched normally by the end user. Other entry points
40 | /// will be used such as when the application is launched to open a specific file.
41 | ///
42 | /// Details about the launch request and process.
43 | protected override void OnLaunched(LaunchActivatedEventArgs e)
44 | {
45 |
46 | #if DEBUG
47 | if (System.Diagnostics.Debugger.IsAttached)
48 | {
49 | this.DebugSettings.EnableFrameRateCounter = true;
50 | }
51 | #endif
52 |
53 | Frame rootFrame = Window.Current.Content as Frame;
54 |
55 | // Do not repeat app initialization when the Window already has content,
56 | // just ensure that the window is active
57 | if (rootFrame == null)
58 | {
59 | // Create a Frame to act as the navigation context and navigate to the first page
60 | rootFrame = new Frame();
61 |
62 | rootFrame.NavigationFailed += OnNavigationFailed;
63 |
64 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
65 | {
66 | //TODO: Load state from previously suspended application
67 | }
68 |
69 | // Place the frame in the current Window
70 | Window.Current.Content = rootFrame;
71 | }
72 |
73 | if (rootFrame.Content == null)
74 | {
75 | // When the navigation stack isn't restored navigate to the first page,
76 | // configuring the new page by passing required information as a navigation
77 | // parameter
78 | rootFrame.Navigate(typeof(MainPage), e.Arguments);
79 | }
80 | // Ensure the current window is active
81 | Window.Current.Activate();
82 | }
83 |
84 | ///
85 | /// Invoked when Navigation to a certain page fails
86 | ///
87 | /// The Frame which failed navigation
88 | /// Details about the navigation failure
89 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
90 | {
91 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
92 | }
93 |
94 | ///
95 | /// Invoked when application execution is being suspended. Application state is saved
96 | /// without knowing whether the application will be terminated or resumed with the contents
97 | /// of memory still intact.
98 | ///
99 | /// The source of the suspend request.
100 | /// Details about the suspend request.
101 | private void OnSuspending(object sender, SuspendingEventArgs e)
102 | {
103 | var deferral = e.SuspendingOperation.GetDeferral();
104 | //TODO: Save application state and stop any background activity
105 | deferral.Complete();
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | [Xx]64/
19 | [Xx]86/
20 | [Bb]uild/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 |
85 | # Visual Studio profiler
86 | *.psess
87 | *.vsp
88 | *.vspx
89 | *.sap
90 |
91 | # TFS 2012 Local Workspace
92 | $tf/
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 | *.DotSettings.user
101 |
102 | # JustCode is a .NET coding add-in
103 | .JustCode
104 |
105 | # TeamCity is a build add-in
106 | _TeamCity*
107 |
108 | # DotCover is a Code Coverage Tool
109 | *.dotCover
110 |
111 | # NCrunch
112 | _NCrunch_*
113 | .*crunch*.local.xml
114 | nCrunchTemp_*
115 |
116 | # MightyMoose
117 | *.mm.*
118 | AutoTest.Net/
119 |
120 | # Web workbench (sass)
121 | .sass-cache/
122 |
123 | # Installshield output folder
124 | [Ee]xpress/
125 |
126 | # DocProject is a documentation generator add-in
127 | DocProject/buildhelp/
128 | DocProject/Help/*.HxT
129 | DocProject/Help/*.HxC
130 | DocProject/Help/*.hhc
131 | DocProject/Help/*.hhk
132 | DocProject/Help/*.hhp
133 | DocProject/Help/Html2
134 | DocProject/Help/html
135 |
136 | # Click-Once directory
137 | publish/
138 |
139 | # Publish Web Output
140 | *.[Pp]ublish.xml
141 | *.azurePubxml
142 |
143 | # TODO: Un-comment the next line if you do not want to checkin
144 | # your web deploy settings because they may include unencrypted
145 | # passwords
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # NuGet Packages
150 | *.nupkg
151 | # The packages folder can be ignored because of Package Restore
152 | **/packages/*
153 | # except build/, which is used as an MSBuild target.
154 | !**/packages/build/
155 | # Uncomment if necessary however generally it will be regenerated when needed
156 | #!**/packages/repositories.config
157 | # NuGet v3's project.json files produces more ignoreable files
158 | *.nuget.props
159 | *.nuget.targets
160 |
161 | # Microsoft Azure Build Output
162 | csx/
163 | *.build.csdef
164 |
165 | # Microsoft Azure Emulator
166 | ecf/
167 | rcf/
168 |
169 | # Microsoft Azure ApplicationInsights config file
170 | ApplicationInsights.config
171 |
172 | # Windows Store app package directory
173 | AppPackages/
174 | BundleArtifacts/
175 |
176 | # Visual Studio cache files
177 | # files ending in .cache can be ignored
178 | *.[Cc]ache
179 | # but keep track of directories ending in .cache
180 | !*.[Cc]ache/
181 |
182 | # Others
183 | ClientBin/
184 | [Ss]tyle[Cc]op.*
185 | ~$*
186 | *~
187 | *.dbmdl
188 | *.dbproj.schemaview
189 | *.pfx
190 | *.publishsettings
191 | node_modules/
192 | orleans.codegen.cs
193 |
194 | # RIA/Silverlight projects
195 | Generated_Code/
196 |
197 | # Backup & report files from converting an old project file
198 | # to a newer Visual Studio version. Backup files are not needed,
199 | # because we have git ;-)
200 | _UpgradeReport_Files/
201 | Backup*/
202 | UpgradeLog*.XML
203 | UpgradeLog*.htm
204 |
205 | # SQL Server files
206 | *.mdf
207 | *.ldf
208 |
209 | # Business Intelligence projects
210 | *.rdl.data
211 | *.bim.layout
212 | *.bim_*.settings
213 |
214 | # Microsoft Fakes
215 | FakesAssemblies/
216 |
217 | # GhostDoc plugin setting file
218 | *.GhostDoc.xml
219 |
220 | # Node.js Tools for Visual Studio
221 | .ntvs_analysis.dat
222 |
223 | # Visual Studio 6 build log
224 | *.plg
225 |
226 | # Visual Studio 6 workspace options file
227 | *.opt
228 |
229 | # Visual Studio LightSwitch build output
230 | **/*.HTMLClient/GeneratedArtifacts
231 | **/*.DesktopClient/GeneratedArtifacts
232 | **/*.DesktopClient/ModelManifest.xml
233 | **/*.Server/GeneratedArtifacts
234 | **/*.Server/ModelManifest.xml
235 | _Pvt_Extensions
236 |
237 | # LightSwitch generated files
238 | GeneratedArtifacts/
239 | ModelManifest.xml
240 |
241 | # Paket dependency manager
242 | .paket/paket.exe
243 |
244 | # FAKE - F# Make
245 | .fake/
--------------------------------------------------------------------------------
/CDFSampleApp/Tasks/Tasks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {CEA8E664-3E8B-4188-808B-BA20B2BE278E}
8 | winmdobj
9 | Properties
10 | Tasks
11 | Tasks
12 | en-US
13 | UAP
14 | 10.0.14393.0
15 | 10.0.10240.0
16 | 14
17 | 512
18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 | false
20 |
21 |
22 | AnyCPU
23 | true
24 | full
25 | false
26 | bin\Debug\
27 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
28 | prompt
29 | 4
30 |
31 |
32 | AnyCPU
33 | pdbonly
34 | true
35 | bin\Release\
36 | TRACE;NETFX_CORE;WINDOWS_UWP
37 | prompt
38 | 4
39 |
40 |
41 | x86
42 | true
43 | bin\x86\Debug\
44 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
45 | ;2008
46 | full
47 | x86
48 | false
49 | prompt
50 |
51 |
52 | x86
53 | bin\x86\Release\
54 | TRACE;NETFX_CORE;WINDOWS_UWP
55 | true
56 | ;2008
57 | pdbonly
58 | x86
59 | false
60 | prompt
61 |
62 |
63 | ARM
64 | true
65 | bin\ARM\Debug\
66 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
67 | ;2008
68 | full
69 | ARM
70 | false
71 | prompt
72 |
73 |
74 | ARM
75 | bin\ARM\Release\
76 | TRACE;NETFX_CORE;WINDOWS_UWP
77 | true
78 | ;2008
79 | pdbonly
80 | ARM
81 | false
82 | prompt
83 |
84 |
85 | x64
86 | true
87 | bin\x64\Debug\
88 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
89 | ;2008
90 | full
91 | x64
92 | false
93 | prompt
94 |
95 |
96 | x64
97 | bin\x64\Release\
98 | TRACE;NETFX_CORE;WINDOWS_UWP
99 | true
100 | ;2008
101 | pdbonly
102 | x64
103 | false
104 | prompt
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | 14.0
116 |
117 |
118 |
125 |
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/CDFSampleApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x86
7 | {9FDD0FF8-7487-428F-8325-D247F2CD3923}
8 | AppContainerExe
9 | Properties
10 | CDFSampleApp_Ashish
11 | CDFSampleApp_Ashish
12 | en-US
13 | UAP
14 | 10.0.14393.0
15 | 10.0.14393.0
16 | 14
17 | 512
18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 | CDFSampleApp_Ashish_TemporaryKey.pfx
20 | True
21 | False
22 | Always
23 | x64
24 |
25 |
26 | true
27 | bin\x86\Debug\
28 | TRACE;DEBUG;NETFX_CORE;WINDOWS_UWP;CODE_ANALYSIS
29 | ;2008
30 | full
31 | x86
32 | false
33 | prompt
34 | true
35 |
36 |
37 | bin\x86\Release\
38 | TRACE;NETFX_CORE;WINDOWS_UWP
39 | true
40 | ;2008
41 | pdbonly
42 | x86
43 | false
44 | prompt
45 | true
46 | true
47 |
48 |
49 | true
50 | bin\ARM\Debug\
51 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
52 | ;2008
53 | full
54 | ARM
55 | false
56 | prompt
57 | true
58 |
59 |
60 | bin\ARM\Release\
61 | TRACE;NETFX_CORE;WINDOWS_UWP
62 | true
63 | ;2008
64 | pdbonly
65 | ARM
66 | false
67 | prompt
68 | true
69 | true
70 |
71 |
72 | true
73 | bin\x64\Debug\
74 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
75 | ;2008
76 | full
77 | x64
78 | false
79 | prompt
80 | true
81 |
82 |
83 | bin\x64\Release\
84 | TRACE;NETFX_CORE;WINDOWS_UWP
85 | true
86 | ;2008
87 | pdbonly
88 | x64
89 | false
90 | prompt
91 | true
92 | true
93 |
94 |
95 |
96 |
97 | PreserveNewest
98 |
99 |
100 |
101 |
102 |
103 | App.xaml
104 |
105 |
106 | MainPage.xaml
107 |
108 |
109 |
110 |
111 |
112 | Designer
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | MSBuild:Compile
129 | Designer
130 |
131 |
132 | MSBuild:Compile
133 | Designer
134 |
135 |
136 |
137 |
138 | {cea8e664-3e8b-4188-808b-ba20b2be278e}
139 | Tasks
140 |
141 |
142 |
143 | 14.0
144 |
145 |
146 |
153 |
--------------------------------------------------------------------------------
/CDFSampleApp/Tasks/myBGTask.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using Windows.ApplicationModel.Background;
8 | using Windows.ApplicationModel.Core;
9 | using Windows.Data.Xml.Dom;
10 | using Windows.Security.Authentication.Identity.Provider;
11 | using Windows.Security.Cryptography;
12 | using Windows.Security.Cryptography.Core;
13 | using Windows.Storage.Streams;
14 | using Windows.UI.Core;
15 | using Windows.UI.Notifications;
16 |
17 | namespace Tasks
18 | {
19 | public sealed class myBGTask : IBackgroundTask
20 | {
21 | ManualResetEvent opCompletedEvent = null;
22 | public void Run(IBackgroundTaskInstance taskInstance)
23 | {
24 | var deferral = taskInstance.GetDeferral();
25 |
26 | // This event is signaled when the operation completes
27 | opCompletedEvent = new ManualResetEvent(false);
28 | SecondaryAuthenticationFactorAuthentication.AuthenticationStageChanged += OnStageChanged;
29 | ShowToastNotification("BG Task Hit!");
30 |
31 | // Wait until the operation completes
32 | opCompletedEvent.WaitOne();
33 |
34 | deferral.Complete();
35 | }
36 |
37 | async void PerformAuthentication()
38 | {
39 | ShowToastNotification("Performing Auth!");
40 |
41 | //Get the selected device from app settings
42 | var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
43 | String m_selectedDeviceId = localSettings.Values["SelectedDevice"] as String;
44 |
45 | SecondaryAuthenticationFactorAuthenticationStageInfo authStageInfo = await SecondaryAuthenticationFactorAuthentication.GetAuthenticationStageInfoAsync();
46 |
47 | if (authStageInfo.Stage != SecondaryAuthenticationFactorAuthenticationStage.CollectingCredential)
48 | {
49 | ShowToastNotification("Unexpected!");
50 | throw new Exception("Unexpected!");
51 | }
52 |
53 | ShowToastNotification("Post Collecting Credential");
54 |
55 | IReadOnlyList deviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(
56 | SecondaryAuthenticationFactorDeviceFindScope.AllUsers);
57 |
58 | if (deviceList.Count == 0)
59 | {
60 | ShowToastNotification("Unexpected exception, device list = 0");
61 | throw new Exception ("Unexpected exception, device list = 0");
62 | }
63 |
64 | ShowToastNotification("Found companion devices");
65 |
66 | SecondaryAuthenticationFactorInfo deviceInfo = deviceList.ElementAt(0);
67 | m_selectedDeviceId = deviceInfo.DeviceId;
68 |
69 | ShowToastNotification("Device ID: " + m_selectedDeviceId);
70 |
71 | //a nonce is an arbitrary number that may only be used once - a random or pseudo-random number issued in an authentication protocol to ensure that old communications cannot be reused in replay attacks.
72 | IBuffer svcNonce = CryptographicBuffer.GenerateRandom(32); //Generate a nonce and do a HMAC operation with the nonce
73 |
74 |
75 | //In real world, you would need to take this nonce and send to companion device to perform an HMAC operation with it
76 | //You will have only 20 second to get the HMAC from the companion device
77 | SecondaryAuthenticationFactorAuthenticationResult authResult = await SecondaryAuthenticationFactorAuthentication.StartAuthenticationAsync(
78 | m_selectedDeviceId, svcNonce);
79 |
80 | if (authResult.Status != SecondaryAuthenticationFactorAuthenticationStatus.Started)
81 | {
82 | ShowToastNotification("Unexpected! Could not start authentication!");
83 | throw new Exception("Unexpected! Could not start authentication!");
84 | }
85 |
86 | ShowToastNotification("Auth Started");
87 |
88 | //
89 | // WARNING: Test code
90 | // The HAMC calculation SHOULD be done on companion device
91 | //
92 | byte[] combinedDataArray;
93 | CryptographicBuffer.CopyToByteArray(authResult.Authentication.DeviceConfigurationData, out combinedDataArray);
94 |
95 | byte[] deviceKeyArray = new byte[32];
96 | byte[] authKeyArray = new byte[32];
97 | for (int index = 0; index < deviceKeyArray.Length; index++)
98 | {
99 | deviceKeyArray[index] = combinedDataArray[index];
100 | }
101 | for (int index = 0; index < authKeyArray.Length; index++)
102 | {
103 | authKeyArray[index] = combinedDataArray[deviceKeyArray.Length + index];
104 | }
105 | // Create device key and authentication key
106 | IBuffer deviceKey = CryptographicBuffer.CreateFromByteArray(deviceKeyArray);
107 | IBuffer authKey = CryptographicBuffer.CreateFromByteArray(authKeyArray);
108 |
109 | // Calculate the HMAC
110 | MacAlgorithmProvider hMACSha256Provider = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256);
111 |
112 | CryptographicKey deviceHmacKey = hMACSha256Provider.CreateKey(deviceKey);
113 | IBuffer deviceHmac = CryptographicEngine.Sign(deviceHmacKey, authResult.Authentication.DeviceNonce);
114 |
115 | // sessionHmac = HMAC(authKey, deviceHmac || sessionNonce)
116 | IBuffer sessionHmac;
117 | byte[] deviceHmacArray = { 0 };
118 | CryptographicBuffer.CopyToByteArray(deviceHmac, out deviceHmacArray);
119 |
120 | byte[] sessionNonceArray = { 0 };
121 | CryptographicBuffer.CopyToByteArray(authResult.Authentication.SessionNonce, out sessionNonceArray);
122 |
123 | combinedDataArray = new byte[deviceHmacArray.Length + sessionNonceArray.Length];
124 | for (int index = 0; index < deviceHmacArray.Length; index++)
125 | {
126 | combinedDataArray[index] = deviceHmacArray[index];
127 | }
128 | for (int index = 0; index < sessionNonceArray.Length; index++)
129 | {
130 | combinedDataArray[deviceHmacArray.Length + index] = sessionNonceArray[index];
131 | }
132 |
133 | // Get a Ibuffer from combinedDataArray
134 | IBuffer sessionMessage = CryptographicBuffer.CreateFromByteArray(combinedDataArray);
135 |
136 | // Calculate sessionHmac
137 | CryptographicKey authHmacKey = hMACSha256Provider.CreateKey(authKey);
138 | sessionHmac = CryptographicEngine.Sign(authHmacKey, sessionMessage);
139 |
140 | ShowToastNotification("Before finish auth");
141 |
142 | SecondaryAuthenticationFactorFinishAuthenticationStatus authStatus = await authResult.Authentication.FinishAuthenticationAsync(deviceHmac,
143 | sessionHmac);
144 |
145 | if (authStatus != SecondaryAuthenticationFactorFinishAuthenticationStatus.Completed)
146 | {
147 | ShowToastNotification("Unable to complete authentication!");
148 | throw new Exception("Unable to complete authentication!");
149 | }
150 |
151 | ShowToastNotification("Auth completed");
152 | }
153 |
154 | public static void ShowToastNotification(string message)
155 | {
156 |
157 | ToastTemplateType toastTemplate = ToastTemplateType.ToastImageAndText01;
158 | XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);
159 |
160 | // Set Text
161 | XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
162 | toastTextElements[0].AppendChild(toastXml.CreateTextNode(message));
163 |
164 | // Set image
165 | // Images must be less than 200 KB in size and smaller than 1024 x 1024 pixels.
166 | XmlNodeList toastImageAttributes = toastXml.GetElementsByTagName("image");
167 | ((XmlElement)toastImageAttributes[0]).SetAttribute("src", "ms-appx:///Images/logo-80px-80px.png");
168 | ((XmlElement)toastImageAttributes[0]).SetAttribute("alt", "logo");
169 |
170 | // toast duration
171 | IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
172 | ((XmlElement)toastNode).SetAttribute("duration", "short");
173 |
174 | // toast navigation
175 | var toastNavigationUriString = "#/MainPage.xaml?param1=12345";
176 | var toastElement = ((XmlElement)toastXml.SelectSingleNode("/toast"));
177 | toastElement.SetAttribute("launch", toastNavigationUriString);
178 |
179 | // Create the toast notification based on the XML content you've specified.
180 | ToastNotification toast = new ToastNotification(toastXml);
181 |
182 | // Send your toast notification.
183 | ToastNotificationManager.CreateToastNotifier().Show(toast);
184 |
185 | }
186 |
187 | // WARNING: Test code
188 | // This code should be in background task
189 | async void OnStageChanged(Object sender, SecondaryAuthenticationFactorAuthenticationStageChangedEventArgs args)
190 | {
191 | //ShowToastNotification("In StageChanged!" + args.StageInfo.Stage.ToString());
192 | if (args.StageInfo.Stage == SecondaryAuthenticationFactorAuthenticationStage.WaitingForUserConfirmation)
193 | {
194 | ShowToastNotification("Stage = WaitingForUserConfirmation");
195 | // This event is happening on a ThreadPool thread, so we need to dispatch to the UI thread.
196 | // Getting the dispatcher from the MainView works as long as we only have one view.
197 | String deviceName = "DeviceSimulator.";
198 | await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync(
199 | deviceName,
200 | SecondaryAuthenticationFactorAuthenticationMessage.SwipeUpWelcome);
201 | }
202 | else if (args.StageInfo.Stage == SecondaryAuthenticationFactorAuthenticationStage.CollectingCredential)
203 | {
204 | ShowToastNotification("Stage = CollectingCredential");
205 |
206 | PerformAuthentication();
207 | }
208 | else
209 | {
210 | if (args.StageInfo.Stage == SecondaryAuthenticationFactorAuthenticationStage.StoppingAuthentication)
211 | {
212 | SecondaryAuthenticationFactorAuthentication.AuthenticationStageChanged -= OnStageChanged;
213 | opCompletedEvent.Set();
214 | }
215 |
216 | SecondaryAuthenticationFactorAuthenticationStage stage = args.StageInfo.Stage;
217 | }
218 | }
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/CDFSampleApp/CDFSampleApp/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel.Background;
7 | using Windows.ApplicationModel.Core;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.Security.Authentication.Identity.Provider;
11 | using Windows.Security.Cryptography;
12 | using Windows.Security.Cryptography.Core;
13 | using Windows.Storage.Streams;
14 | using Windows.UI.Core;
15 | using Windows.UI.Popups;
16 | using Windows.UI.Xaml;
17 | using Windows.UI.Xaml.Controls;
18 | using Windows.UI.Xaml.Controls.Primitives;
19 | using Windows.UI.Xaml.Data;
20 | using Windows.UI.Xaml.Input;
21 | using Windows.UI.Xaml.Media;
22 | using Windows.UI.Xaml.Navigation;
23 |
24 | // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
25 |
26 | namespace CDFSampleApp_Ashish
27 | {
28 | ///
29 | /// An empty page that can be used on its own or navigated to within a Frame.
30 | ///
31 | public sealed partial class MainPage : Page
32 | {
33 | String m_selectedDeviceId = String.Empty;
34 | bool taskRegistered = false;
35 | static string myBGTaskName = "myBGTask";
36 | static string myBGTaskEntryPoint = "Tasks.myBGTask";
37 |
38 | public MainPage()
39 | {
40 | this.InitializeComponent();
41 |
42 | DeviceListBox.SelectionChanged += DeviceListBox_SelectionChanged;
43 | }
44 |
45 | protected override async void OnNavigatedTo(NavigationEventArgs e)
46 | {
47 | base.OnNavigatedTo(e);
48 |
49 | IReadOnlyList deviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(SecondaryAuthenticationFactorDeviceFindScope.User);
50 |
51 | RefreshDeviceList(deviceList);
52 |
53 | }
54 |
55 | void RefreshDeviceList(IReadOnlyList deviceList)
56 | {
57 | DeviceListBox.Items.Clear();
58 |
59 | for (int index = 0; index < deviceList.Count; ++index)
60 | {
61 | SecondaryAuthenticationFactorInfo deviceInfo = deviceList.ElementAt(index);
62 | DeviceListBox.Items.Add(deviceInfo.DeviceId);
63 | }
64 | }
65 |
66 | private async void RegisterDevice_Click(object sender, RoutedEventArgs e)
67 | {
68 | String deviceId = System.Guid.NewGuid().ToString();
69 |
70 | // WARNING: Test code
71 | // These keys should be generated on the companion device
72 | // Create device key and authentication key
73 | IBuffer deviceKey = CryptographicBuffer.GenerateRandom(32);
74 | IBuffer authKey = CryptographicBuffer.GenerateRandom(32);
75 |
76 | //
77 | // WARNING: Test code
78 | // The keys SHOULD NOT be saved into device config data
79 | //
80 | byte[] deviceKeyArray = { 0 };
81 | CryptographicBuffer.CopyToByteArray(deviceKey, out deviceKeyArray);
82 |
83 | byte[] authKeyArray = { 0 };
84 | CryptographicBuffer.CopyToByteArray(authKey, out authKeyArray);
85 |
86 | //Generate combinedDataArray
87 | int combinedDataArraySize = deviceKeyArray.Length + authKeyArray.Length;
88 | byte[] combinedDataArray = new byte[combinedDataArraySize];
89 | for (int index = 0; index < deviceKeyArray.Length; index++)
90 | {
91 | combinedDataArray[index] = deviceKeyArray[index];
92 | }
93 | for (int index = 0; index < authKeyArray.Length; index++)
94 | {
95 | combinedDataArray[deviceKeyArray.Length + index] = authKeyArray[index];
96 | }
97 |
98 | // Get a Ibuffer from combinedDataArray
99 | IBuffer deviceConfigData = CryptographicBuffer.CreateFromByteArray(combinedDataArray);
100 |
101 | //
102 | // WARNING: Test code
103 | // The friendly name and device model number SHOULD come from device
104 | //
105 | String deviceFriendlyName = "Test Simulator";
106 | String deviceModelNumber = "Sample A1";
107 |
108 | SecondaryAuthenticationFactorDeviceCapabilities capabilities = SecondaryAuthenticationFactorDeviceCapabilities.SecureStorage;
109 |
110 | SecondaryAuthenticationFactorRegistrationResult registrationResult = await SecondaryAuthenticationFactorRegistration.RequestStartRegisteringDeviceAsync(deviceId,
111 | capabilities,
112 | deviceFriendlyName,
113 | deviceModelNumber,
114 | deviceKey,
115 | authKey);
116 |
117 | if (registrationResult.Status != SecondaryAuthenticationFactorRegistrationStatus.Started)
118 | {
119 | MessageDialog myDlg = null;
120 |
121 | if (registrationResult.Status == SecondaryAuthenticationFactorRegistrationStatus.DisabledByPolicy)
122 | {
123 | //For DisaledByPolicy Exception:Ensure secondary auth is enabled.
124 | //Use GPEdit.msc to update group policy to allow secondary auth
125 | //Local Computer Policy\Computer Configuration\Administrative Templates\Windows Components\Microsoft Secondary Authentication Factor\Allow Companion device for secondary authentication
126 | myDlg = new MessageDialog("Disabled by Policy. Please update the policy and try again.");
127 | }
128 |
129 | if (registrationResult.Status == SecondaryAuthenticationFactorRegistrationStatus.PinSetupRequired)
130 | {
131 | //For PinSetupRequired Exception:Ensure PIN is setup on the device
132 | //Either use gpedit.msc or set reg key
133 | //This setting can be enabled by creating the AllowDomainPINLogon REG_DWORD value under the HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System Registry key and setting it to 1.
134 | myDlg = new MessageDialog("Please setup PIN for your device and try again.");
135 | }
136 |
137 | if (myDlg != null)
138 | {
139 | await myDlg.ShowAsync();
140 | return;
141 | }
142 | }
143 |
144 | System.Diagnostics.Debug.WriteLine("Device Registration Started!");
145 | await registrationResult.Registration.FinishRegisteringDeviceAsync(deviceConfigData);
146 |
147 | DeviceListBox.Items.Add(deviceId);
148 | System.Diagnostics.Debug.WriteLine("Device Registration is Complete!");
149 |
150 | IReadOnlyList deviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(
151 | SecondaryAuthenticationFactorDeviceFindScope.User);
152 |
153 | RefreshDeviceList(deviceList);
154 | }
155 |
156 | private void DeviceListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
157 | {
158 | if (DeviceListBox.Items.Count > 0)
159 | {
160 | m_selectedDeviceId = DeviceListBox.SelectedItem.ToString();
161 | }
162 | else
163 | {
164 | m_selectedDeviceId = String.Empty;
165 | }
166 | System.Diagnostics.Debug.WriteLine("The device " + m_selectedDeviceId + " is selected.");
167 |
168 | //Store the selected device in settings to be used in the BG task
169 | var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
170 | localSettings.Values["SelectedDevice"] = m_selectedDeviceId;
171 |
172 | }
173 |
174 | private async void UnregisterDevice_Click(object sender, RoutedEventArgs e)
175 | {
176 | if (m_selectedDeviceId == String.Empty)
177 | {
178 | return;
179 | }
180 |
181 | //InfoList.Items.Add("Unregister a device:");
182 |
183 | await SecondaryAuthenticationFactorRegistration.UnregisterDeviceAsync(m_selectedDeviceId);
184 |
185 | //InfoList.Items.Add("Device unregistration is completed.");
186 |
187 | IReadOnlyList deviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(
188 | SecondaryAuthenticationFactorDeviceFindScope.User);
189 |
190 | RefreshDeviceList(deviceList);
191 | }
192 |
193 |
194 | void RegisterBgTask_Click(object sender, RoutedEventArgs e)
195 | {
196 | RegisterTask();
197 | }
198 |
199 |
200 | private async void OnBgTaskProgress(BackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs args)
201 | {
202 | // WARNING: Test code
203 | // Handle background task progress.
204 | if (args.Progress == 1)
205 | {
206 | await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
207 | {
208 | System.Diagnostics.Debug.WriteLine("Background task is started.");
209 | });
210 | }
211 | }
212 |
213 | async void RegisterTask()
214 | {
215 | System.Diagnostics.Debug.WriteLine("Register the background task.");
216 | //
217 | // Check for existing registrations of this background task.
218 | //
219 |
220 | BackgroundExecutionManager.RemoveAccess();
221 | var access = await BackgroundExecutionManager.RequestAccessAsync();
222 |
223 | foreach (var task in BackgroundTaskRegistration.AllTasks)
224 | {
225 | if (task.Value.Name == myBGTaskName)
226 | {
227 | taskRegistered = true;
228 | break;
229 | }
230 | }
231 |
232 | if (!taskRegistered)
233 | {
234 |
235 | if (access == BackgroundAccessStatus.AllowedSubjectToSystemPolicy)
236 | {
237 | BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder();
238 | taskBuilder.Name = myBGTaskName;
239 | // Create the trigger.
240 | SecondaryAuthenticationFactorAuthenticationTrigger myTrigger = new SecondaryAuthenticationFactorAuthenticationTrigger();
241 |
242 | taskBuilder.TaskEntryPoint = myBGTaskEntryPoint;
243 | taskBuilder.SetTrigger(myTrigger);
244 | BackgroundTaskRegistration taskReg = taskBuilder.Register();
245 |
246 | String taskRegName = taskReg.Name;
247 | //taskReg.Progress += OnBgTaskProgress;
248 | System.Diagnostics.Debug.WriteLine("Background task registration is completed.");
249 | taskRegistered = true;
250 | }
251 | }
252 |
253 | }
254 | }
255 | }
--------------------------------------------------------------------------------