Skip to content

Commit d2f015a

Browse files
authored
Use SHA2 and PSS for client assertion (#4616)
* Fix tests * Remove other JSON operations * Perf tests * codeql * PR comments * fix
1 parent 8b49739 commit d2f015a

File tree

30 files changed

+523
-384
lines changed

30 files changed

+523
-384
lines changed

.editorconfig

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ dotnet_style_predefined_type_for_member_access = true:suggestion
5959
# name all constant fields using PascalCase
6060
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
6161
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
62-
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
62+
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
6363

6464
dotnet_naming_symbols.constant_fields.applicable_kinds = field
6565
dotnet_naming_symbols.constant_fields.required_modifiers = const
@@ -69,7 +69,7 @@ dotnet_naming_style.pascal_case_style.capitalization = pascal_case
6969
# static fields should have s_ prefix
7070
dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
7171
dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
72-
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
72+
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
7373

7474
dotnet_naming_symbols.static_fields.applicable_kinds = field
7575
dotnet_naming_symbols.static_fields.required_modifiers = static
@@ -80,7 +80,7 @@ dotnet_naming_style.static_prefix_style.capitalization = camel_case
8080
# internal and private fields should be _camelCase
8181
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
8282
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
83-
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
83+
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
8484

8585
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
8686
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
@@ -140,6 +140,23 @@ csharp_space_between_method_declaration_name_and_open_parenthesis = false
140140
csharp_space_between_method_declaration_parameter_list_parentheses = false
141141
csharp_space_between_parentheses = false
142142
csharp_space_between_square_brackets = false
143+
csharp_using_directive_placement = outside_namespace:silent
144+
csharp_prefer_simple_using_statement = true:suggestion
145+
csharp_prefer_braces = true:silent
146+
csharp_style_namespace_declarations = block_scoped:silent
147+
csharp_style_prefer_method_group_conversion = true:silent
148+
csharp_style_prefer_top_level_statements = true:silent
149+
csharp_style_prefer_primary_constructors = true:suggestion
150+
csharp_style_expression_bodied_lambdas = true:silent
151+
csharp_style_expression_bodied_local_functions = false:silent
152+
csharp_style_prefer_null_check_over_type_check = true:suggestion
153+
csharp_prefer_simple_default_expression = true:suggestion
154+
csharp_style_prefer_local_over_anonymous_function = true:suggestion
155+
csharp_style_prefer_index_operator = true:suggestion
156+
csharp_style_prefer_range_operator = true:suggestion
157+
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
158+
csharp_style_prefer_tuple_swap = true:suggestion
159+
csharp_style_prefer_utf8_string_literals = true:suggestion
143160

144161
# C++ Files
145162

@@ -826,7 +843,7 @@ dotnet_diagnostic.CA1832.severity = none
826843
dotnet_diagnostic.CA1833.severity = none
827844

828845
# Consider using 'StringBuilder.Append(char)' when applicable
829-
dotnet_diagnostic.CA1834.severity = none
846+
dotnet_diagnostic.CA1834.severity = warning
830847

831848
# Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
832849
dotnet_diagnostic.CA1835.severity = none
@@ -1284,3 +1301,21 @@ dotnet_diagnostic.RS1012.severity = none
12841301
dotnet_diagnostic.RS1013.severity = none
12851302

12861303
dotnet_diagnostic.RS1014.severity = none
1304+
dotnet_style_operator_placement_when_wrapping = beginning_of_line
1305+
tab_width = 4
1306+
dotnet_style_coalesce_expression = true:suggestion
1307+
dotnet_style_null_propagation = true:suggestion
1308+
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
1309+
dotnet_style_prefer_auto_properties = true:silent
1310+
dotnet_style_object_initializer = true:suggestion
1311+
dotnet_style_prefer_collection_expression = true:suggestion
1312+
dotnet_style_collection_initializer = true:suggestion
1313+
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
1314+
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
1315+
dotnet_style_prefer_conditional_expression_over_return = true:silent
1316+
dotnet_style_explicit_tuple_names = true:suggestion
1317+
dotnet_style_prefer_inferred_tuple_names = true:suggestion
1318+
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
1319+
dotnet_style_prefer_compound_assignment = true:suggestion
1320+
dotnet_style_prefer_simplified_interpolation = true:suggestion
1321+
dotnet_style_namespace_match_folder = true:suggestion

src/client/Microsoft.Identity.Client/AppConfig/AuthorityInfo.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ private AuthorityInfo(
138138
AuthorityType == AuthorityType.B2C ||
139139
AuthorityType == AuthorityType.Ciam;
140140

141+
/// <summary>
142+
/// True if SHA2 and PSS can be used for creating the client credential from a certificate
143+
/// </summary>
144+
internal bool IsSha2CredentialSupported =>
145+
AuthorityType != AuthorityType.Dsts &&
146+
AuthorityType != AuthorityType.Generic &&
147+
AuthorityType != AuthorityType.Adfs;
148+
141149
#region Builders
142150
internal static AuthorityInfo FromAuthorityUri(string authorityUri, bool validateAuthority)
143151
{

src/client/Microsoft.Identity.Client/AuthScheme/PoP/PoPAuthenticationScheme.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ public string FormatAccessToken(MsalAccessTokenCacheItem msalAccessTokenCacheIte
7575
}
7676

7777
var header = new JObject();
78-
header[JsonWebTokenConstants.ReservedHeaderParameters.Algorithm] = _popCryptoProvider.CryptographicAlgorithm;
79-
header[JsonWebTokenConstants.ReservedHeaderParameters.KeyId] = KeyId;
80-
header[JsonWebTokenConstants.ReservedHeaderParameters.Type] = Constants.PoPTokenType;
78+
header[JsonWebTokenConstants.Algorithm] = _popCryptoProvider.CryptographicAlgorithm;
79+
header[JsonWebTokenConstants.KeyId] = KeyId;
80+
header[JsonWebTokenConstants.Type] = Constants.PoPTokenType;
8181

8282
var body = CreateBody(msalAccessTokenCacheItem);
8383

src/client/Microsoft.Identity.Client/Internal/ClientCredential/CertificateAndClaimsClientCredential.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
using System;
45
using System.Collections.Generic;
6+
using System.Runtime.ConstrainedExecution;
7+
using System.Security.Cryptography;
58
using System.Security.Cryptography.X509Certificates;
69
using System.Threading;
710
using System.Threading.Tasks;
@@ -17,17 +20,20 @@ internal class CertificateAndClaimsClientCredential : IClientCredential
1720
{
1821
private readonly IDictionary<string, string> _claimsToSign;
1922
private readonly bool _appendDefaultClaims;
20-
private readonly string _base64EncodedThumbprint; // x5t
23+
2124
public X509Certificate2 Certificate { get; }
2225

2326
public AssertionType AssertionType => AssertionType.CertificateWithoutSni;
2427

25-
public CertificateAndClaimsClientCredential(X509Certificate2 certificate, IDictionary<string, string> claimsToSign, bool appendDefaultClaims)
28+
public CertificateAndClaimsClientCredential(
29+
X509Certificate2 certificate,
30+
IDictionary<string, string> claimsToSign,
31+
bool appendDefaultClaims)
2632
{
2733
Certificate = certificate;
2834
_claimsToSign = claimsToSign;
2935
_appendDefaultClaims = appendDefaultClaims;
30-
_base64EncodedThumbprint = Base64UrlHelpers.Encode(certificate.GetCertHash());
36+
3137
}
3238

3339
public Task AddConfidentialClientParametersAsync(
@@ -37,6 +43,7 @@ public Task AddConfidentialClientParametersAsync(
3743
string clientId,
3844
string tokenEndpoint,
3945
bool sendX5C,
46+
bool useSha2AndPss,
4047
CancellationToken cancellationToken)
4148
{
4249
var jwtToken = new JsonWebToken(
@@ -46,7 +53,7 @@ public Task AddConfidentialClientParametersAsync(
4653
_claimsToSign,
4754
_appendDefaultClaims);
4855

49-
string assertion = jwtToken.Sign(Certificate, _base64EncodedThumbprint, sendX5C);
56+
string assertion = jwtToken.Sign(Certificate, sendX5C, useSha2AndPss);
5057

5158
oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertionType, OAuth2AssertionType.JwtBearer);
5259
oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertion, assertion);

src/client/Microsoft.Identity.Client/Internal/ClientCredential/IClientCredential.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Task AddConfidentialClientParametersAsync(
2727
string clientId,
2828
string tokenEndpoint,
2929
bool sendX5C,
30+
bool useSha2,
3031
CancellationToken cancellationToken);
3132
}
3233
}

src/client/Microsoft.Identity.Client/Internal/ClientCredential/SecretStringClientCredential.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ public SecretStringClientCredential(string secret)
2222
Secret = secret;
2323
}
2424

25-
public Task AddConfidentialClientParametersAsync(OAuth2Client oAuth2Client, ILoggerAdapter logger, ICryptographyManager cryptographyManager, string clientId, string tokenEndpoint, bool sendX5C, CancellationToken cancellationToken)
25+
public Task AddConfidentialClientParametersAsync(
26+
OAuth2Client oAuth2Client,
27+
ILoggerAdapter logger,
28+
ICryptographyManager cryptographyManager,
29+
string clientId,
30+
string tokenEndpoint,
31+
bool sendX5C,
32+
bool useSha2,
33+
CancellationToken cancellationToken)
2634
{
2735
oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientSecret, Secret);
2836
return Task.CompletedTask;

src/client/Microsoft.Identity.Client/Internal/ClientCredential/SignedAssertionClientCredential.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ public SignedAssertionClientCredential(string signedAssertion)
2222
_signedAssertion = signedAssertion;
2323
}
2424

25-
public Task AddConfidentialClientParametersAsync(OAuth2Client oAuth2Client, ILoggerAdapter logger, ICryptographyManager cryptographyManager, string clientId, string tokenEndpoint, bool sendX5C, CancellationToken cancellationToken)
25+
public Task AddConfidentialClientParametersAsync(
26+
OAuth2Client oAuth2Client,
27+
ILoggerAdapter logger,
28+
ICryptographyManager cryptographyManager,
29+
string clientId,
30+
string tokenEndpoint,
31+
bool sendX5C,
32+
bool useSha2,
33+
CancellationToken cancellationToken)
2634
{
2735
oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertionType, OAuth2AssertionType.JwtBearer);
2836
oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertion, _signedAssertion);

src/client/Microsoft.Identity.Client/Internal/ClientCredential/SignedAssertionDelegateClientCredential.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,15 @@ public SignedAssertionDelegateClientCredential(Func<AssertionRequestOptions, Tas
2828
_signedAssertionWithInfoDelegate = signedAssertionDelegate;
2929
}
3030

31-
public async Task AddConfidentialClientParametersAsync(OAuth2Client oAuth2Client, ILoggerAdapter logger, ICryptographyManager cryptographyManager, string clientId, string tokenEndpoint, bool sendX5C, CancellationToken cancellationToken)
31+
public async Task AddConfidentialClientParametersAsync(
32+
OAuth2Client oAuth2Client,
33+
ILoggerAdapter logger,
34+
ICryptographyManager cryptographyManager,
35+
string clientId,
36+
string tokenEndpoint,
37+
bool sendX5C,
38+
bool useSha2,
39+
CancellationToken cancellationToken)
3240
{
3341
string signedAssertion = await (_signedAssertionDelegate != null
3442
? _signedAssertionDelegate(cancellationToken).ConfigureAwait(false)
@@ -41,5 +49,6 @@ public async Task AddConfidentialClientParametersAsync(OAuth2Client oAuth2Client
4149
oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertionType, OAuth2AssertionType.JwtBearer);
4250
oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientAssertion, signedAssertion);
4351
}
52+
4453
}
4554
}

0 commit comments

Comments
 (0)