Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.

Commit 8d0a1fb

Browse files
author
David R. Williamson
committed
Revamp DPS TPM sample
1 parent 5302f5c commit 8d0a1fb

File tree

12 files changed

+257
-190
lines changed

12 files changed

+257
-190
lines changed

provisioning/Samples/device/Common/ProvisioningDeviceClientSample.cs

Lines changed: 0 additions & 79 deletions
This file was deleted.

provisioning/Samples/device/SymmetricKeySample/ProvisioningDeviceClientSample.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ public async Task RunSampleAsync()
5353
security,
5454
transportHandler);
5555

56-
Console.WriteLine($"Initialized for registration Id {security.GetRegistrationID()}");
56+
Console.WriteLine($"Initialized for registration Id {security.GetRegistrationID()}.");
5757

58-
Console.WriteLine("Registering with the device provisioning service... ");
58+
Console.WriteLine("Registering with the device provisioning service...");
5959
DeviceRegistrationResult result = await provClient.RegisterAsync();
6060

6161
Console.WriteLine($"Registration status: {result.Status}.");
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using CommandLine;
5+
using Microsoft.Azure.Devices.Client;
6+
7+
namespace Microsoft.Azure.Devices.Provisioning.Client.Samples
8+
{
9+
/// <summary>
10+
/// Parameters for the application
11+
/// </summary>
12+
internal class Parameters
13+
{
14+
[Option(
15+
'e',
16+
"GetTpmEndorsementKey",
17+
HelpText = "Gets the TPM endorsement key. Use this option by itself to get the EK needed to create a DPS individual enrollment.")]
18+
public bool GetTpmEndorsementKey { get; set; }
19+
20+
[Option(
21+
'u',
22+
"UseTpmSimulator",
23+
HelpText = "Runs the TPM simulator - useful when the local device does not have a TPM chip.")]
24+
public bool UseTpmSimulator { get; set; }
25+
26+
[Option(
27+
's',
28+
"IdScope",
29+
HelpText = "The Id Scope of the DPS instance. For normal runs, this is required.")]
30+
public string IdScope { get; set; }
31+
32+
[Option(
33+
'r',
34+
"RegistrationId",
35+
HelpText = "The registration Id from the individual enrollment. For normal runs, this is required.")]
36+
public string RegistrationId { get; set; }
37+
38+
[Option(
39+
'g',
40+
"GlobalDeviceEndpoint",
41+
Default = "global.azure-devices-provisioning.net",
42+
HelpText = "The global endpoint for devices to connect to.")]
43+
public string GlobalDeviceEndpoint { get; set; }
44+
45+
[Option(
46+
't',
47+
"TransportType",
48+
Default = TransportType.Amqp,
49+
HelpText = "The transport to use to communicate with the device provisioning instance. Possible values include Amqp, Amqp_WebSocket_Only, Amqp_Tcp_only, and Http1.")]
50+
public TransportType TransportType { get; set; }
51+
}
52+
}

provisioning/Samples/device/TpmSample/Program.cs

Lines changed: 42 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,64 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4-
using Microsoft.Azure.Devices.Provisioning.Client;
5-
using Microsoft.Azure.Devices.Provisioning.Client.Transport;
4+
using CommandLine;
5+
using Microsoft.Azure.Devices.Provisioning.Security;
66
using Microsoft.Azure.Devices.Provisioning.Security.Samples;
7-
using Microsoft.Azure.Devices.Shared;
87
using System;
8+
using System.Threading.Tasks;
99

1010
namespace Microsoft.Azure.Devices.Provisioning.Client.Samples
1111
{
12+
/// <summary>
13+
/// A sample to illustrate connecting a device to hub using the device provisioning service and a certificate.
14+
/// </summary>
1215
public static class Program
1316
{
14-
// The Provisioning Hub IDScope.
15-
16-
// For this sample either:
17-
// - pass this value as a command-prompt argument
18-
// - set the DPS_IDSCOPE environment variable
19-
// - create a launchSettings.json (see launchSettings.json.template) containing the variable
20-
private static string s_idScope = Environment.GetEnvironmentVariable("DPS_IDSCOPE");
21-
22-
private const string RegistrationId = "testtpmregistration1";
23-
private const string GlobalDeviceEndpoint = "global.azure-devices-provisioning.net";
24-
25-
public static int Main(string[] args)
17+
public static async Task<int> Main(string[] args)
2618
{
27-
if (string.IsNullOrWhiteSpace(s_idScope) && (args.Length > 0))
28-
{
29-
s_idScope = args[0];
30-
}
31-
32-
if (string.IsNullOrWhiteSpace(s_idScope))
33-
{
34-
Console.WriteLine("ProvisioningDeviceClientTpm <IDScope>");
35-
return 1;
36-
}
37-
38-
// Remove if a real TPM is being used.
39-
Console.WriteLine("Starting TPM simulator.");
40-
SecurityProviderTpmSimulator.StartSimulatorProcess();
41-
42-
// Replace the following type with SecurityProviderTpmHsm() to use a real TPM2.0 device.
43-
using (var security = new SecurityProviderTpmSimulator(RegistrationId))
19+
// Parse application parameters
20+
Parameters parameters = null;
21+
ParserResult<Parameters> result = Parser.Default.ParseArguments<Parameters>(args)
22+
.WithParsed(parsedParams =>
23+
{
24+
parameters = parsedParams;
25+
})
26+
.WithNotParsed(errors =>
27+
{
28+
Environment.Exit(1);
29+
});
4430

45-
// Select one of the available transports:
46-
// To optimize for size, reference only the protocols used by your application.
47-
using (var transport = new ProvisioningTransportHandlerHttp())
48-
// using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly))
49-
// using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.WebSocketOnly))
31+
// This sample provides a way to get the endorsement key (EK) required in creation of the individual enrollment
32+
if (parameters.GetTpmEndorsementKey)
5033
{
51-
// Note that the TPM simulator will create an NVChip file containing the simulated TPM state.
52-
Console.WriteLine("Extracting endorsement key.");
53-
string base64EK = Convert.ToBase64String(security.GetEndorsementKey());
34+
if (parameters.UseTpmSimulator)
35+
{
36+
Console.WriteLine("Starting TPM simulator...");
37+
SecurityProviderTpmSimulator.StartSimulatorProcess();
38+
}
5439

55-
Console.WriteLine(
56-
"In your Azure Device Provisioning Service please go to 'Manage enrollments' and select " +
57-
"'Individual Enrollments'. Select 'Add' then fill in the following:");
40+
using var security = new SecurityProviderTpmHsm(null);
41+
Console.WriteLine($"Your EK is {Convert.ToBase64String(security.GetEndorsementKey())}");
5842

59-
Console.WriteLine("\tMechanism: TPM");
60-
Console.WriteLine($"\tRegistration ID: {RegistrationId}");
61-
Console.WriteLine($"\tEndorsement key: {base64EK}");
62-
Console.WriteLine("\tDevice ID: iothubtpmdevice1 (or any other valid DeviceID)");
63-
Console.WriteLine();
64-
Console.WriteLine("Press ENTER when ready.");
65-
Console.ReadLine();
43+
if (parameters.UseTpmSimulator)
44+
{
45+
SecurityProviderTpmSimulator.StopSimulatorProcess();
46+
}
6647

67-
ProvisioningDeviceClient provClient =
68-
ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, s_idScope, security, transport);
48+
return 0;
49+
}
6950

70-
var sample = new ProvisioningDeviceClientSample(provClient, security);
71-
sample.RunSampleAsync().GetAwaiter().GetResult();
51+
// For a normal run of this sample, IdScope and RegistrationId are required
52+
if (string.IsNullOrWhiteSpace(parameters.IdScope)
53+
|| string.IsNullOrWhiteSpace(parameters.RegistrationId))
54+
{
55+
Console.WriteLine(CommandLine.Text.HelpText.AutoBuild(result, null, null));
56+
Environment.Exit(1);
7257
}
7358

59+
var sample = new ProvisioningDeviceClientSample(parameters);
60+
await sample.RunSampleAsync();
61+
7462
return 0;
7563
}
7664
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using Microsoft.Azure.Devices.Client;
5+
using Microsoft.Azure.Devices.Provisioning.Client.Transport;
6+
using Microsoft.Azure.Devices.Provisioning.Security;
7+
using Microsoft.Azure.Devices.Provisioning.Security.Samples;
8+
using Microsoft.Azure.Devices.Shared;
9+
using System;
10+
using System.Text;
11+
using System.Threading.Tasks;
12+
13+
namespace Microsoft.Azure.Devices.Provisioning.Client.Samples
14+
{
15+
/// <summary>
16+
/// Demonstrates how to register a device with the device provisioning service using a certificate, and then
17+
/// use the registration information to authenticate to IoT Hub.
18+
/// </summary>
19+
internal class ProvisioningDeviceClientSample
20+
{
21+
private readonly Parameters _parameters;
22+
23+
public ProvisioningDeviceClientSample(Parameters parameters)
24+
{
25+
_parameters = parameters;
26+
}
27+
28+
public async Task RunSampleAsync()
29+
{
30+
SecurityProviderTpm security = null;
31+
32+
try
33+
{
34+
if (_parameters.UseTpmSimulator)
35+
{
36+
Console.WriteLine("Starting TPM simulator...");
37+
SecurityProviderTpmSimulator.StartSimulatorProcess();
38+
security = new SecurityProviderTpmSimulator(_parameters.RegistrationId);
39+
}
40+
else
41+
{
42+
Console.WriteLine("Initializing security using the local TPM...");
43+
security = new SecurityProviderTpmHsm(_parameters.RegistrationId);
44+
}
45+
46+
Console.WriteLine($"Initializing the device provisioning client...");
47+
48+
using var transport = GetTransportHandler();
49+
ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(
50+
_parameters.GlobalDeviceEndpoint,
51+
_parameters.IdScope,
52+
security,
53+
transport);
54+
55+
Console.WriteLine($"Initialized for registration Id {security.GetRegistrationID()}.");
56+
57+
Console.WriteLine("Registering with the device provisioning service... ");
58+
DeviceRegistrationResult result = await provClient.RegisterAsync();
59+
60+
Console.WriteLine($"Registration status: {result.Status}.");
61+
if (result.Status != ProvisioningRegistrationStatusType.Assigned)
62+
{
63+
Console.WriteLine($"Registration status did not assign a hub, so exiting this sample.");
64+
return;
65+
}
66+
67+
Console.WriteLine($"Device {result.DeviceId} registered to {result.AssignedHub}.");
68+
69+
Console.WriteLine("Creating TPM authentication for IoT Hub...");
70+
IAuthenticationMethod auth = new DeviceAuthenticationWithTpm(result.DeviceId, security);
71+
72+
Console.WriteLine($"Testing the provisioned device with IoT Hub...");
73+
using DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, _parameters.TransportType);
74+
75+
Console.WriteLine("Sending a telemetry message...");
76+
using var message = new Message(Encoding.UTF8.GetBytes("TestMessage"));
77+
await iotClient.SendEventAsync(message);
78+
}
79+
finally
80+
{
81+
if (_parameters.UseTpmSimulator)
82+
{
83+
SecurityProviderTpmSimulator.StopSimulatorProcess();
84+
}
85+
86+
security?.Dispose();
87+
}
88+
89+
Console.WriteLine("Finished.");
90+
}
91+
92+
private ProvisioningTransportHandler GetTransportHandler()
93+
{
94+
return _parameters.TransportType switch
95+
{
96+
TransportType.Amqp => new ProvisioningTransportHandlerAmqp(),
97+
TransportType.Amqp_Tcp_Only => new ProvisioningTransportHandlerAmqp(TransportFallbackType.WebSocketOnly),
98+
TransportType.Amqp_WebSocket_Only => new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly),
99+
TransportType.Http1 => new ProvisioningTransportHandlerHttp(),
100+
TransportType.Mqtt => throw new NotSupportedException("MQTT is not supported for TPM"),
101+
TransportType.Mqtt_Tcp_Only => throw new NotSupportedException("MQTT is not supported for TPM"),
102+
TransportType.Mqtt_WebSocket_Only => throw new NotSupportedException("MQTT is not supported for TPM"),
103+
_ => throw new NotSupportedException($"Unsupported transport type {_parameters.TransportType}"),
104+
};
105+
}
106+
}
107+
}

provisioning/Samples/device/TpmSample/TpmSample.csproj

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<Compile Include="..\Common\ProvisioningDeviceClientSample.cs" Link="ProvisioningDeviceClientSample.cs" />
12-
</ItemGroup>
13-
14-
<ItemGroup>
11+
<PackageReference Include="CommandLineParser" Version="2.8.0" />
1512
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.33.1" />
1613
<PackageReference Include="Microsoft.Azure.Devices.Provisioning.Client" Version="1.*" />
17-
<PackageReference Include="Microsoft.Azure.Devices.Provisioning.Security.Tpm" Version="1.*" />
14+
<PackageReference Include="Microsoft.Azure.Devices.Provisioning.Security.Tpm" Version="1.12.2" />
1815

19-
<!-- Note: Applications should not need to import both protocols. This was done to simplify protocol selection within the sample.-->
16+
<!-- Note: Applications should not need to import all 3 protocols. This was done to simplify protocol selection within the sample.-->
2017
<PackageReference Include="Microsoft.Azure.Devices.Provisioning.Transport.Amqp" Version="1.13.3" />
2118
<PackageReference Include="Microsoft.Azure.Devices.Provisioning.Transport.Http" Version="1.12.2" />
19+
<PackageReference Include="Microsoft.Azure.Devices.Provisioning.Transport.Mqtt" Version="1.13.2" />
2220
</ItemGroup>
2321

2422
<ItemGroup>

0 commit comments

Comments
 (0)