-
Notifications
You must be signed in to change notification settings - Fork 403
Managed Identity IMDSv2 and new support APIs (ResetForTest, GetSourceAsync) #5501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 41 commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
38dbae3
CSR Metadata request acts as a probe for ImdsV2 (#5359)
Robbie-Microsoft 4b2453d
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft faa28bc
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 7bc1735
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 024e7b4
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 8c03bb3
Imdsv2: Generate CSR and execute CSR request (#5427)
Robbie-Microsoft 24f599a
Minor adjustments
Robbie-Microsoft b75e879
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft ea15d19
private -> public, for unit tests
Robbie-Microsoft 2ce7e1b
ImdsV2: Implemented downlevel polyfill for CertificateRequest (#5454)
Robbie-Microsoft fdf2038
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft ddc2117
ImdsV2: Acquire Entra Token Over mTLS (#5431)
Robbie-Microsoft d0b0edf
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 5825f50
ImdsV2: Miscellanious Updates Discovered by Manual Testing (#5477)
Robbie-Microsoft 15bbfc1
ImdsV2: Added Additional Headers to the Entra Token Request (#5459)
Robbie-Microsoft d41a874
MSIV2: net8.0 Unit Test Fixes (#5480)
Robbie-Microsoft 8c4c255
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 2518f1b
MSI V2 - Adding Attestation package for mTLS POP MSI flows (#5483)
gladjohn e06b4b0
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 8099d17
Fixed broken unit test + created helper function for code re-use
Robbie-Microsoft 774e01e
MSI V2 client side keys (#5448)
gladjohn 0897cce
ImdsV2: Integrated .WithMtlsProofOfPossession (#5490)
Robbie-Microsoft 717e59e
[MSI v2] - Pass the actual resource to IMDS (#5497)
gladjohn d180eb1
ImdsV2: Entra Request: "expires_in" is now lumped into "expires_on" (…
Robbie-Microsoft 42587b5
ImdsV2: WithExtraQueryParameters (#5492)
Robbie-Microsoft 693e917
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft c2eddde
Add ResetStateForTest API for test (#5489)
bgavrilMS 087130e
undid commit where code was supopsed to be stashed
Robbie-Microsoft 89ff42a
[MSI v2] - Enable attestation in pop flows (#5496)
gladjohn 8464e83
ImdsV2: .WithMtlsProofOfPossession Will Throw on NET462 for Managed I…
Robbie-Microsoft c706896
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 1ae351b
IMDSv2: Fixed Broken Unit Test (#5516)
Robbie-Microsoft 1c399c3
ImdsV2: Throw on MTLS when OS is not Windows (#5520)
Robbie-Microsoft 732c9d6
ImdsV2: Added Caching for the IMDS Endpoint Env Variable + Improved U…
Robbie-Microsoft 2fc14f7
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft ce4f407
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 16f0280
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 8922b98
[MSI V2] - Adds Authentication Operation to MSI v2 mTLS flows (#5533)
gladjohn f7e3973
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 358a9d8
ImdsV2: Non-mTLS POP Requests Fall Back to ImdsV1 (#5531)
Robbie-Microsoft 57f2815
Merge branch 'main' into rginsburg/msiv2_feature_branch
Robbie-Microsoft 4b284c3
[MSI v2] Cache MSI v2 cert (#5557)
gladjohn 94e482d
Remove custom loader from mTLS interop (#5561)
gladjohn d57a5d5
ImdsV2: Temporary Workaround for Resource Id Query Param Bug in IMDS …
Robbie-Microsoft File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
src/client/Microsoft.Identity.Client.MtlsPop/Attestation/AttestationClient.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System; | ||
| using System.Runtime.InteropServices; | ||
| using Microsoft.Win32.SafeHandles; | ||
|
|
||
| namespace Microsoft.Identity.Client.MtlsPop.Attestation | ||
| { | ||
| /// <summary> | ||
| /// Managed façade for <c>AttestationClientLib.dll</c>. Holds initialization state, | ||
| /// does ref-count hygiene on <see cref="SafeNCryptKeyHandle"/>, and returns a JWT. | ||
| /// </summary> | ||
| internal sealed class AttestationClient : IDisposable | ||
| { | ||
| private bool _initialized; | ||
|
|
||
| /// <summary> | ||
| /// AttestationClient constructor. Pro-actively verifies the native DLL. | ||
| /// </summary> | ||
| /// <exception cref="InvalidOperationException"></exception> | ||
| public AttestationClient() | ||
| { | ||
| /* step 0 ── ensure the resolver probes all valid locations | ||
| (env override → app base → System32/SysWOW64 → PATH) */ | ||
| NativeDllResolver.EnsureLoaded(); | ||
|
|
||
| /* step 1 ── optional proactive verification (non-fatal) | ||
| Keep the probe for diagnostics, but do NOT throw here; if the DLL | ||
| is truly unavailable/mismatched, InitAttestationLib will fail. */ | ||
| string dllError = NativeDiagnostics.ProbeNativeDll(); | ||
| // intentionally not throwing on dllError to avoid path-specific false negatives | ||
|
|
||
| /* step 2 ── load & initialize (logger is required by native lib) */ | ||
| var info = new AttestationClientLib.AttestationLogInfo | ||
| { | ||
| Log = AttestationLogger.ConsoleLogger, // minimal rooted delegate; works on netstandard2.0 & net8.0 | ||
| Ctx = IntPtr.Zero | ||
| }; | ||
|
|
||
| _initialized = AttestationClientLib.InitAttestationLib(ref info) == 0; | ||
| if (!_initialized) | ||
| throw new InvalidOperationException("Failed to initialize AttestationClientLib."); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Calls the native <c>AttestKeyGuardImportKey</c> and returns a structured result. | ||
| /// </summary> | ||
| public AttestationResult Attest(string endpoint, | ||
| SafeNCryptKeyHandle keyHandle, | ||
| string clientId) | ||
| { | ||
| if (!_initialized) | ||
| return new(AttestationStatus.NotInitialized, null, -1, | ||
| "Native library not initialized."); | ||
|
|
||
| IntPtr buf = IntPtr.Zero; | ||
| bool addRef = false; | ||
|
|
||
| try | ||
| { | ||
| keyHandle.DangerousAddRef(ref addRef); | ||
|
|
||
| int rc = AttestationClientLib.AttestKeyGuardImportKey( | ||
| endpoint, null, null, keyHandle, out buf, clientId); | ||
|
|
||
| if (rc != 0) | ||
| return new(AttestationStatus.NativeError, null, rc, null); | ||
|
|
||
| if (buf == IntPtr.Zero) | ||
| return new(AttestationStatus.TokenEmpty, null, 0, | ||
| "rc==0 but token buffer was null."); | ||
|
|
||
| string jwt = Marshal.PtrToStringAnsi(buf)!; | ||
| return new(AttestationStatus.Success, jwt, 0, null); | ||
| } | ||
| catch (DllNotFoundException ex) | ||
| { | ||
| return new(AttestationStatus.Exception, null, -1, | ||
| $"Native DLL not found: {ex.Message}"); | ||
| } | ||
| catch (BadImageFormatException ex) | ||
| { | ||
| return new(AttestationStatus.Exception, null, -1, | ||
| $"Architecture mismatch (x86/x64) or corrupted DLL: {ex.Message}"); | ||
| } | ||
| catch (SEHException ex) | ||
| { | ||
| return new(AttestationStatus.Exception, null, -1, | ||
| $"Native library raised SEHException: {ex.Message}"); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| return new(AttestationStatus.Exception, null, -1, ex.Message); | ||
| } | ||
| finally | ||
| { | ||
| if (buf != IntPtr.Zero) | ||
| AttestationClientLib.FreeAttestationToken(buf); | ||
| if (addRef) | ||
| keyHandle.DangerousRelease(); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Disposes the client, releasing any resources and un-initializing the native library. | ||
| /// </summary> | ||
| public void Dispose() | ||
| { | ||
| if (_initialized) | ||
| { | ||
| AttestationClientLib.UninitAttestationLib(); | ||
| _initialized = false; | ||
| } | ||
| GC.SuppressFinalize(this); | ||
| } | ||
| } | ||
| } |
45 changes: 45 additions & 0 deletions
45
src/client/Microsoft.Identity.Client.MtlsPop/Attestation/AttestationClientLib.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using Microsoft.Win32.SafeHandles; | ||
| using System; | ||
| using System.IO; | ||
| using System.Runtime.InteropServices; | ||
|
|
||
| namespace Microsoft.Identity.Client.MtlsPop.Attestation | ||
| { | ||
| internal static class AttestationClientLib | ||
| { | ||
| internal enum LogLevel { Error, Warn, Info, Debug } | ||
|
|
||
| internal delegate void LogFunc( | ||
| IntPtr ctx, string tag, LogLevel lvl, string func, int line, string msg); | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal struct AttestationLogInfo | ||
| { | ||
| public LogFunc Log; | ||
| public IntPtr Ctx; | ||
| } | ||
|
|
||
| [DllImport("AttestationClientLib.dll", CallingConvention = CallingConvention.Cdecl, | ||
| CharSet = CharSet.Ansi)] | ||
| internal static extern int InitAttestationLib(ref AttestationLogInfo info); | ||
|
|
||
| [DllImport("AttestationClientLib.dll", CallingConvention = CallingConvention.Cdecl, | ||
| CharSet = CharSet.Ansi)] | ||
| internal static extern int AttestKeyGuardImportKey( | ||
| string endpoint, | ||
| string authToken, | ||
| string clientPayload, | ||
| SafeNCryptKeyHandle keyHandle, | ||
| out IntPtr token, | ||
| string clientId); | ||
|
|
||
| [DllImport("AttestationClientLib.dll", CallingConvention = CallingConvention.Cdecl)] | ||
| internal static extern void FreeAttestationToken(IntPtr token); | ||
|
|
||
| [DllImport("AttestationClientLib.dll", CallingConvention = CallingConvention.Cdecl)] | ||
| internal static extern void UninitAttestationLib(); | ||
| } | ||
| } |
27 changes: 27 additions & 0 deletions
27
src/client/Microsoft.Identity.Client.MtlsPop/Attestation/AttestationErrors.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Text; | ||
|
|
||
| namespace Microsoft.Identity.Client.MtlsPop.Attestation | ||
| { | ||
| internal static class AttestationErrors | ||
| { | ||
| internal static string Describe(AttestationResultErrorCode rc) => rc switch | ||
| { | ||
| AttestationResultErrorCode.ERRORCURLINITIALIZATION | ||
| => "libcurl failed to initialize (DLL missing or version mismatch).", | ||
| AttestationResultErrorCode.ERRORHTTPREQUESTFAILED | ||
| => "Could not reach the attestation service (network / proxy?).", | ||
| AttestationResultErrorCode.ERRORATTESTATIONFAILED | ||
| => "The enclave rejected the evidence (key type / PCR policy).", | ||
| AttestationResultErrorCode.ERRORJWTDECRYPTIONFAILED | ||
| => "The JWT returned by the service could not be decrypted.", | ||
| AttestationResultErrorCode.ERRORLOGGERINITIALIZATION | ||
| => "Native logger setup failed (rare).", | ||
| _ => rc.ToString() // default: enum name | ||
| }; | ||
| } | ||
| } |
51 changes: 51 additions & 0 deletions
51
src/client/Microsoft.Identity.Client.MtlsPop/Attestation/AttestationLogger.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System; | ||
| using System.Diagnostics; | ||
| using System.Runtime.InteropServices; | ||
|
|
||
| namespace Microsoft.Identity.Client.MtlsPop.Attestation | ||
| { | ||
| internal static class AttestationLogger | ||
| { | ||
| /// <summary> | ||
| /// Attestation Logger | ||
| /// </summary> | ||
| internal static readonly AttestationClientLib.LogFunc ConsoleLogger = (ctx, tag, lvl, func, line, msg) => | ||
| { | ||
| try | ||
| { | ||
| string sTag = ToText(tag); | ||
| string sFunc = ToText(func); | ||
| string sMsg = ToText(msg); | ||
|
|
||
| var lineText = $"[MtlsPop][{lvl}] {sTag} {sFunc}:{line} {sMsg}"; | ||
|
|
||
| // Default: Trace (respects listeners; safe for all app types) | ||
| Trace.WriteLine(lineText); | ||
|
|
||
| // Opt-in console mirroring for local debugging | ||
| if (Environment.GetEnvironmentVariable("MSAL_MTLSPOP_LOG_TO_CONSOLE") == "1") | ||
| { | ||
| Console.WriteLine(lineText); | ||
| } | ||
| } | ||
| catch | ||
| { | ||
| } | ||
| }; | ||
|
|
||
| // Converts either string or IntPtr (char*) to text. Works with any LogFunc variant. | ||
| private static string ToText(object value) | ||
| { | ||
| if (value is IntPtr p && p != IntPtr.Zero) | ||
| { | ||
| try | ||
| { return Marshal.PtrToStringAnsi(p) ?? string.Empty; } | ||
| catch { return string.Empty; } | ||
| } | ||
| return value?.ToString() ?? string.Empty; | ||
| } | ||
| } | ||
| } | ||
18 changes: 18 additions & 0 deletions
18
src/client/Microsoft.Identity.Client.MtlsPop/Attestation/AttestationResult.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| namespace Microsoft.Identity.Client.MtlsPop.Attestation | ||
| { | ||
| /// <summary> | ||
| /// AttestationResult is the result of an attestation operation. | ||
| /// </summary> | ||
| /// <param name="Status"></param> | ||
| /// <param name="Jwt"></param> | ||
| /// <param name="NativeErrorCode"></param> | ||
| /// <param name="ErrorMessage"></param> | ||
| internal sealed record AttestationResult( | ||
| AttestationStatus Status, | ||
| string Jwt, | ||
| int NativeErrorCode, | ||
| string ErrorMessage); | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.