|
1 | 1 | // Copyright (c) Microsoft. All rights reserved. |
2 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
3 | 3 |
|
4 | | -using Microsoft.Azure.Devices.Provisioning.Client; |
5 | | -using Microsoft.Azure.Devices.Provisioning.Client.Transport; |
6 | | -using Microsoft.Azure.Devices.Shared; |
| 4 | +using CommandLine; |
7 | 5 | using System; |
8 | | -using System.IO; |
9 | | -using System.Security.Cryptography.X509Certificates; |
10 | | -using System.Text; |
| 6 | +using System.Threading.Tasks; |
11 | 7 |
|
12 | 8 | namespace Microsoft.Azure.Devices.Provisioning.Client.Samples |
13 | 9 | { |
| 10 | + /// <summary> |
| 11 | + /// A sample to illustrate connecting a device to hub using the device provisioning service and a certificate. |
| 12 | + /// </summary> |
14 | 13 | public static class Program |
15 | 14 | { |
16 | | - // The Provisioning Hub IDScope. |
17 | | - |
18 | | - // For this sample either: |
19 | | - // - pass this value as a command-prompt argument |
20 | | - // - set the DPS_IDSCOPE environment variable |
21 | | - // - create a launchSettings.json (see launchSettings.json.template) containing the variable |
22 | | - private static string s_idScope = Environment.GetEnvironmentVariable("DPS_IDSCOPE"); |
23 | | - |
24 | | - // In your Device Provisioning Service please go to "Manage enrollments" and select "Individual Enrollments". |
25 | | - // Select "Add individual enrollment" then fill in the following: |
26 | | - // Mechanism: X.509 |
27 | | - // Certificate: |
28 | | - // You can generate a self-signed certificate by running the GenerateTestCertificate.ps1 powershell script. |
29 | | - // Select the public key 'certificate.cer' file. ('certificate.pfx' contains the private key and is password protected.) |
30 | | - // For production code, it is advised that you install the certificate in the CurrentUser (My) store. |
31 | | - // DeviceID: iothubx509device1 |
32 | | - |
33 | | - // X.509 certificates may also be used for enrollment groups. |
34 | | - // In your Device Provisioning Service please go to "Manage enrollments" and select "Enrollment Groups". |
35 | | - // Select "Add enrollment group" then fill in the following: |
36 | | - // Group name: <your group name> |
37 | | - // Attestation Type: Certificate |
38 | | - // Certificate Type: |
39 | | - // choose CA certificate then link primary and secondary certificates |
40 | | - // OR choose Intermediate certificate and upload primary and secondary certificate files |
41 | | - // You may also change other enrollemtn group parameters according to your needs |
42 | | - |
43 | | - private const string GlobalDeviceEndpoint = "global.azure-devices-provisioning.net"; |
44 | | - private static string s_certificateFileName = "certificate.pfx"; |
45 | | - |
46 | | - public static int Main(string[] args) |
| 15 | + public static async Task<int> Main(string[] args) |
47 | 16 | { |
48 | | - if (string.IsNullOrWhiteSpace(s_idScope) && (args.Length > 0)) |
49 | | - { |
50 | | - s_idScope = args[0]; |
51 | | - } |
52 | | - |
53 | | - if (string.IsNullOrWhiteSpace(s_idScope)) |
54 | | - { |
55 | | - Console.WriteLine("ProvisioningDeviceClientX509 <IDScope>"); |
56 | | - return 1; |
57 | | - } |
58 | | - |
59 | | - X509Certificate2 certificate = LoadProvisioningCertificate(); |
60 | | - |
61 | | - using (var security = new SecurityProviderX509Certificate(certificate)) |
62 | | - |
63 | | - // Select one of the available transports: |
64 | | - // To optimize for size, reference only the protocols used by your application. |
65 | | - using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly)) |
66 | | - // using (var transport = new ProvisioningTransportHandlerHttp()) |
67 | | - // using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly)) |
68 | | - // using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly)) |
69 | | - { |
70 | | - ProvisioningDeviceClient provClient = |
71 | | - ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, s_idScope, security, transport); |
72 | | - |
73 | | - var sample = new ProvisioningDeviceClientSample(provClient, security); |
74 | | - sample.RunSampleAsync().GetAwaiter().GetResult(); |
75 | | - } |
76 | | - |
77 | | - return 0; |
78 | | - } |
79 | | - |
80 | | - private static X509Certificate2 LoadProvisioningCertificate() |
81 | | - { |
82 | | - string certificatePassword = ReadCertificatePassword(); |
83 | | - |
84 | | - var certificateCollection = new X509Certificate2Collection(); |
85 | | - certificateCollection.Import(s_certificateFileName, certificatePassword, X509KeyStorageFlags.UserKeySet); |
86 | | - |
87 | | - X509Certificate2 certificate = null; |
88 | | - |
89 | | - foreach (X509Certificate2 element in certificateCollection) |
90 | | - { |
91 | | - Console.WriteLine($"Found certificate: {element?.Thumbprint} {element?.Subject}; PrivateKey: {element?.HasPrivateKey}"); |
92 | | - if (certificate == null && element.HasPrivateKey) |
| 17 | + // Parse application parameters |
| 18 | + Parameters parameters = null; |
| 19 | + ParserResult<Parameters> result = Parser.Default.ParseArguments<Parameters>(args) |
| 20 | + .WithParsed(parsedParams => |
93 | 21 | { |
94 | | - certificate = element; |
95 | | - } |
96 | | - else |
| 22 | + parameters = parsedParams; |
| 23 | + }) |
| 24 | + .WithNotParsed(errors => |
97 | 25 | { |
98 | | - element.Dispose(); |
99 | | - } |
100 | | - } |
| 26 | + Environment.Exit(1); |
| 27 | + }); |
101 | 28 |
|
102 | | - if (certificate == null) |
103 | | - { |
104 | | - throw new FileNotFoundException($"{s_certificateFileName} did not contain any certificate with a private key."); |
105 | | - } |
106 | | - else |
107 | | - { |
108 | | - Console.WriteLine($"Using certificate {certificate.Thumbprint} {certificate.Subject}"); |
109 | | - } |
| 29 | + var sample = new ProvisioningDeviceClientSample(parameters); |
| 30 | + await sample.RunSampleAsync(); |
110 | 31 |
|
111 | | - return certificate; |
112 | | - } |
113 | | - |
114 | | - private static string ReadCertificatePassword() |
115 | | - { |
116 | | - var password = new StringBuilder(); |
117 | | - Console.WriteLine($"Enter the PFX password for {s_certificateFileName}:"); |
118 | | - |
119 | | - while(true) |
120 | | - { |
121 | | - ConsoleKeyInfo key = Console.ReadKey(true); |
122 | | - if (key.Key == ConsoleKey.Backspace) |
123 | | - { |
124 | | - if (password.Length > 0) |
125 | | - { |
126 | | - password.Remove(password.Length - 1, 1); |
127 | | - Console.Write("\b \b"); |
128 | | - } |
129 | | - } |
130 | | - else if (key.Key == ConsoleKey.Enter) |
131 | | - { |
132 | | - Console.WriteLine(); |
133 | | - break; |
134 | | - } |
135 | | - else |
136 | | - { |
137 | | - Console.Write('*'); |
138 | | - password.Append(key.KeyChar); |
139 | | - } |
140 | | - } |
141 | | - |
142 | | - return password.ToString(); |
| 32 | + return 0; |
143 | 33 | } |
144 | 34 | } |
145 | 35 | } |
0 commit comments