diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index f6ec0a4e1da7e2..447d17d5160111 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "1.0.0-prerelease.22074.1", + "version": "1.0.0-prerelease.22101.2", "commands": [ "xharness" ] diff --git a/.github/fabricbot.json b/.github/fabricbot.json index accae195f26ee0..bb429f3f8d9354 100644 --- a/.github/fabricbot.json +++ b/.github/fabricbot.json @@ -190,6 +190,14 @@ "dotnet/area-system-runtime-intrinsics" ] }, + { + "labels": [ + "area-System.Runtime.InteropServices" + ], + "mentionees": [ + "dotnet/interop-contrib" + ] + }, { "labels": [ "area-System.CodeDom" @@ -9969,5 +9977,1227 @@ } ] } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "isOrgProject": true + } + } + ] + } } -] \ No newline at end of file +] diff --git a/docs/area-owners.md b/docs/area-owners.md index 70cc2e4e82fdd9..b310d60381e72a 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -4,7 +4,7 @@ If you need to tag folks on an issue or PR, you will generally want to tag the o ## Areas -Note: Editing this file doesn't update the mapping used by the `@msftbot` issue notification bot to tag owners. Some area owners prefer not to get those notifications. To update those notifications, contact any one of `@danmoseley`, `@jeffschw`, `@marek-safar`, `@ericstj`, `@karelz`, or `@jeffhandley`; they have permissions to update [`msftbot` configuration](https://portal.fabricbot.ms/bot/?repo=dotnet/runtime). If you're a community member interested in these notifications, you won't appear in this table but we can add you to notifications - just let us know. +Note: Editing this file doesn't update the mapping used by `@msftbot` for area-specific issue/PR notifications. That configuration is part of the [`fabricbot.json`](../.github/fabricbot.json) file, and many areas use GitHub teams for those notifications. If you're a community member interested in receiving area-specific issue/PR notifications, you won't appear in this table or be added to those GitHub teams, but you can create a PR that updates `fabricbot.json` to add yourself to those notifications. See [automation.md](infra/automation.md) for more information on the schema and tools used by FabricBot. | Area | Lead | Owners (area experts to tag in PR's and issues) | Notes | |------------------------------------------------|---------------|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| diff --git a/docs/coding-guidelines/libraries-packaging.md b/docs/coding-guidelines/libraries-packaging.md index 66909e4df855cf..be1a1c8ae8fda8 100644 --- a/docs/coding-guidelines/libraries-packaging.md +++ b/docs/coding-guidelines/libraries-packaging.md @@ -92,6 +92,3 @@ In order to mitigate design-time/build-time performance issues with source gener CustomPropertyName ``` - -### .NETFramework RID specific assets -When targeting .NETFramework, RID specific assets are automatically added to the package if the project contains other compatible RID specific assets, mainly `netstandard2.0-windows`. diff --git a/docs/design/features/OsrDetailsAndDebugging.md b/docs/design/features/OsrDetailsAndDebugging.md new file mode 100644 index 00000000000000..9f479f689a5abd --- /dev/null +++ b/docs/design/features/OsrDetailsAndDebugging.md @@ -0,0 +1,493 @@ +# OSR Details and Debugging + +This document describes some of the rationale behind OSR, things you +may need to think about when OSR is enabled, and some debugging +techniques that you can use when things go wrong. + +It is primarily aimed at JIT developers but may prove useful to a +broader audience. + +## Background + +OSR (On Stack Replacement) describes the ability of the runtime to +transfer control from one native code version to another while there +are active stack frames for the method. + +The primary goal of OSR is to allow the runtime to initially jit most +methods without optimization, and then transition control (via OSR) if +and when the invocations of those methods become compute +intensive. During a transition the active invocations are rewritten +"on stack" to have the proper frame shape and code references. + +In this way OSR is similar to tiering, but tiering can only change +between native code versions when a method is called. So, for +instance, if a user puts all their code inside loops in `Main` then +tiering will never have an opportunity to update the code being run, +as `Main` is only ever called once. + +OSR is also in many ways similar to EnC (Edit and Continue), though +there are key differences. EnC transitions are initiated by user +edits via the debugger, and typically this means the IL version of the +method has changed. OSR transitions are mediated by the runtime, and +the transitioned-to methods represent different native code +compilation of the same IL code version. + +In our particular implementation OSR is used to transition from a +Tier0 (or "quick") jitted (and hence unoptimized) native code +version to an OSR version that is optimized. OSR versions of the +native code for a method are unusual in many ways; we discuss this +further below. + +For more detail on the OSR design, see the References section. + +### Tiered Compilation + +OSR is built on top of Tiered Compilation, which we briefly recap. + +Tiered Compilation is a runtime and jit feature that allows methods to +be initially jitted quickly, without optimization, and then be +rejitted later on with optimization, if the methods are frequently +called. This allows applications to start up quickly as less time +is spent jitting up front, but still obtain full steady-state +performance over time. + +There are different polices that apply to determine which methods +are handled via tiered compilation, and how they are optimized. +* The normal case is that a method is first quickly jitted (at Tier0) +and then rejitted (at Tier1) (on a background thread) once the +method has been called frequently. +* If a method has been prejitted then the prejitted code serves +the place of the Tier0 code. +* Some methods bypass tiering and are immediately optimized +the first time they are jitted: + * Methods marked with the `AggressiveOptimization` attribute + * Dynamic methods and methods from collectible assemblies + * By default in .NET 3.0, 5.0, 6.0: methods with loops. +This policy is controlled by `DOTNET_COMPlus_TC_QuickJitForLoops`; + see next section. + +### Dynamic and Full PGO + +Dynamic PGO was introduced in the .NET 6.0 release. It also relies +on tiered compilation. + +In Dynamic PGO, any method jitted at Tier0 has additional +instrumentation code added to the Tier0 version to collect profile +data. This data is made available to JIT when the method is +recompiled at Tier1. + +Full PGO is an offshoot of Dynamic PGO where we force all methods +to pass through Tier0. + +### Quick Jit For Loops (aka `QJFL`) + +Tiered compilation was introduced in the .NET Core 3.0 release. + +Initially, all methods that got jitted went through Tier0. But +during the development cycle we got a fair amount of feedback that +this had adverse performance impacts as performance-sensitive user +code could be trapped in the Tier0 version. + +In response to this we changed the default behavior: methods with +loops would be initially optimized and not participate in tiered jitting. +We often use the shorthand `QJFL=0` to describe this behavior. + +While `QJFL=0` addressed the immediate problems users had with tiered +compilation, it had some downsides: + +* Not all methods with loops are performance sensitive, so in many +cases we saw increased startup JIT time without any steady state +benefit. In some applications where startup JIT time is significant +the impact was on the order of 20%. + +* In fact, early optimization of methods may lead to lower +steady-state performance, because (a) class initializers may not yet +have run, so early optimized methods must run class initializer checks +and also cannot examine readonly static fields; (b) Dynamic PGO can +only operate on methods that pass through Tier0. + +One can change the default behavior by setting QJFL to 1; some +startup-sensitive applications (eg `Powershell`) do this. + +### Rationale for Enabling OSR + +OSR allows the runtime to jit most methods at Tier0, and to transition +from Tier0 code when and if needed, and so allows us to change the +default to `QJFL=1`. + +Enabling OSR will lead to: +* better startup perf in general (upwards of 20% in some cases) +* improved steady state perf +* improved perf from Dynamic PGO (closing the gap between Dynamic + PGO and Full PGO) + +## How OSR Works + +### Enabling OSR + +OSR is enabled by setting +`DOTNET_TC_QuickJitForLoops=1` (aka `QJFL=1`) +`DOTNET_TC_OnStackReplacement=1` (aka `OSR=1`) + +and is influenced by +`DOTNET_TieredPGO=1` (`BBINSTR=1` at TIER0) + +### Choosing which methods are "OSR Eligible" + +The runtime makes a JIT request at TIER0, and passes the current +values of QJFL, OSR, and BBINSTR. + +The JIT does an initial IL scan for the method; during this scan it +checks for several things: +* if there is any lexically backwards IL branch (`compHasBackwardsBranch`) +* if there is any lexically backwards branch in catch, filter, finally, +or fault region (aka "loop in handler"). +* if there is any `localloc` +* if the method is a reverse PInvoke +* if there is any `tail.` prefixed call. + +If `QJFL=0 && compHasBackwardsBranch`, the JIT changes the +optimization level to full opt and notifies the runtime that the +method is no longer going to participate in tiered compilation. +This is the default behavior in older releases. + +If `QJFL=1 && OSR==0 && !compHasBackwardsBranch`, the JIT compiles the +method at Tier0. + +If `QJFL=1 && OSR==1 && compHasBackwardsBranch`, the JIT checks to see +if the method has a loop in a handler, localloc, or is a reverse +PInvoke. If not, the method is "OSR Eligible". If so, the JIT will +switch the method to optimized. + +If there is a `tail.` prefixed call and BBINSTR=0, the JIT will +override all the above and switch the method to optimized. + +### Jitting of OSR Eligible Methods at Tier0 + +During importation, the jit looks for blocks that are the targets of +the lexical back edges. It marks these as needing patchpoints. Note these +points are required to be stack empty points in valid IL. + +During the patchpoint phase, if any block was marked, the jit adds a +new integer local to the method (the patchpoint counter) and adds IR +to initialize the counter on method entry to the value of +`DOTNET_TC_OnStackReplacement_InitialCounter` (by default this is +0x1000). + +At each marked block the JIT adds code to decrement the counter and +conditionally invoke `CORINFO_HELP_PATCHPOINT` if the counter value is zero +or negative. The helper arguments are the IL offset of the block and +the address of the counter. + +The remainder of compilation proceeds normally, but when the method is +finished, the JIT creates a patchpoint descriptor to note the method's +frame size, virtual offset of all IL locals, and the offset of some +other key frame information (generics context, etc). This descriptor +is passed back to the runtime, where it is stored alongside the +method's debug info. + +We rely on the fact that Tier0 methods are not optimized and do not +keep any IL state in registers at stack empty points, and there is a +one to one mapping between IL state and stack slots. Thus a single +patchpoint descriptor suffices for all the patchpoints in the method +and no liveness analysis is required to determine what it should +contain. + +A Tier0 method may contain many patchpoints. In our current +implementation the runtime may create one OSR method per patchpoint. +Each OSR method may comprise most or all of the original method. So in the worst case we can have a lot of OSR codegen, but it is currently thought such cases +will be rare. We may need to implement some policy to avoid this. + +### Execution of Tier0 Code with Patchpoints + +When a Tier0 method with Patchpoints is called, it counts down the +per-call patchpoint counter each time a patchpoint is reached. + +If the counter reaches zero the code invokes the +`CORINFO_HELP_PATCHPOINT` runtime helper. The helper then uses the +return address of the helper call as a key into a patchpoint info +table. + +The first time the patchpoint is seen by the runtime it adds an entry +to the table. The local counter in the method is reloaded with a value +determined by `DOTNET_OSR_CounterBump` (currently 0x1000). If a +patchpoint at a given offset is hit more than `DOTNET_OSR_HitLimit` times +(currently 0x10) then the runtime will create an OSR method for that +offset. + +Note this means that a single call can trigger OSR creation after +(0x1000 x 0x11) ~ 69,000 executions at that offset. This number was +chosen to try and balance the perf loss from continued execution of +the Tier0 code versus the one time cost to create the optimized OSR +version and the expected perf win from subsequent execution in the OSR +code. It may need some adjusting. + +The OSR method is created synchronously on the thread that hits the +hit limit threshold. If a second thread arrives while the OSR method +is being created it will simply have its counter reloaded and continue +executing Tier0 code for the time being. Eventually it may come back. + +Once the method is ready the initiating thread is transitioned to the +OSR method; any subsequently arriving executions from other active +frames will likewise transition as they hit the patchpoint. + +The OSR method does not return control to the Tier0 method (it is a +"full continuation" of the Tier0 method at the patchpoint). + +### Creation of the OSR Method + +The OSR method is specific to a Tier0 method at a specific IL +offset. When the runtime decides to create an OSR method it invokes +the jit and passes a special OSR flag and the IL offset. + +This compilation is similar to a normal optimized compilation, with +a few twists: +* Importation starts at the specified IL offset and pulls in all the +code reachable from that point. Typically (but not always) the method entry (IL offset 0) is unreachable +and so the OSR method only imports a subset of the full method. +* Control normally branches from the first block (`fgFirstBB`) to the block at the OSR IL offset (the "osr entry"). +Special care is needed when the osr entry is in the middle of a try or in a nested try. +* If dynamic PGO is enabled the OSR method will read the PGO data captured by the Tier0 +method, but we also instrument the OSR method to ensure any Tier1 version we produce +later on sees all the PGO data it would have seen if we'd forcibly kept the method at Tier0. + +The JIT may need to import the entry block if it can be reached by tail +recursion to loop optimizations, even if there no explicit IL branch +to offset 0 in the IL reachable from the OSR IL offset. This was the +source of a number of subtle bugs -- the call site that eventually may +loop back to the method entry could come from an inlinee, or via +devirtualization, etc. + +For the most part the jit treats an OSR method just like any other +optimized jitted method. But aside from importation, frame layout, +PGO, and prolog/epilog codegen details bleed through in only a handful +of places. + +One of these is that an OSR method will never need to zero init any locals or see undefined values for locals; all this is dealt with by the Tier0 frame. (The OSR method may still need to zero temps it has allocated). + +#### Frame Layout + +For and OSR method, the OSR frame logically "incorporates" the Tier0 method frame. Because the OSR method has different register saves and different temporaries, there is an OSR specific portion of the frame that extends beyond the Tier0 frame. + +On x64, Tier0 frames are always RBP frames. On Arm64, Tier0 frames can be any of the 5 frame types the jit can create. + +On x64 we currently have the frame pointer (if needed) refer to the base of the OSR extension. On arm64 the frame pointer refers to the base of the Tier0 frame. This divergence is historical and we should likely fix x64 to follow the same plan as arm64. + +Locals corresponding to Tier0 args or locals (aka `lvaIsOSRLocal`) that have stack homes in OSR methods will use the Tier0 slot for that home in the OSR method. So it is not uncommon for the OSR method to be accessing parts of the Tier0 frame throughout its execution. Those slots are reported to GC as necessary. + +But often much of the Tier0 frame is effectively dead after the transition and execution of the OSR method's prolog, as the Tier0 live state is enregistered by the OSR method. + +#### OSR Prolog + +The OSR prolog is conceptually similar to a normal method prolog, with a few key difference. + +When an OSR method is entered, all callee-save registers have the values they had when the Tier0 method was called, but the values in argument registers are unknown (and almost certainly not the args passed to the Tier0 method). The OSR method must initialize any live-in enregistered args or locals from the corresponding slots on the Tier0 frame. This happens in `genEnregisterOSRArgsAndLocals`. + +If the OSR method needs to report a generics context it uses the Tier0 frame slot; we ensure this is possible by forcing a Tier0 method with patchpoints to always report its generics context. + +An OSR method does not need to register function entry callbacks as it is never called; similarly it does not need to acquire the synchronous method monitor, as the Tier0 frame will have already done that. + +#### OSR Epilog + +The OSR epilog does the following: +* undoes the OSR contribution to the frame (SP add) +* restores the callee-saved registers saved by the OSR prolog +* undoes the Tier0 frame (SP add) +* restores any Tier0 callees saves needed (x64 only, restores RPB) +* returns to the Tier0/OSR method's caller + +This epilog has a non-standard format because of the two SP adjustments. +This is currently breaking x64 epilog unwind. + +On Arm64 we have epilog unwind codes and the second SP adjust does not appear to cause problems. + +#### Funclets in OSR Methods + +OSR funclets are more or less normal funclets. + +On Arm64, to satisfy PSPSYm reporting constraints, the funclet frame must be padded to include the Tier0 frame size. This is conceptually similar to the way the funclet frames also pad for homed varargs arguments -- in both cases the padded space is never used, it is just there to ensure the PSPSym ends up at the same caller-SP relative offset for the main function and any funclet. + +#### OSR Unwind Info + +On x64 the prolog unwind includes a phantom SP adjustment at offset 0 for the Tier0 frame. + +As noted above the two SP adjusts in the x64 epilog are currently causing problems if we try and unwind in the epilog. Unwinding in the prolog and method body seems to work correctly; the unwind codes properly describe what needs to be done. + +On arm64 there are unwind codes for epilogs and this problem does not seem to arise. + +When an OSR method is active, stack frames will show just that method and not the Tier0 method. + +#### OSR GC Info + +OSR GC info is standard. The only unusual aspect is that some special offsets (generics context, etc) may refer to slots in the Tier0 frame. + +### Execution of an OSR Method + +OSR methods are never called directly; they can only be invoked by `CORINFO_HELP_PATCHPOINT` when called from a Tier0 method with patchpoints. + +On x64, to preserve proper stack alignment, the runtime helper will "push" a phantom return address on the stack (x64 methods assume SP is aligned 8 mod 16 on entry). This is not necessary on arm64 as calls do not push to the stack. + +When the OSR method returns, it cleans up both its own stack and the +Tier0 method stack. + +Note if a Tier0 method is recursive and has loops there can be some interesting dynamics. After a sufficient amount of looping an OSR method will be created, and the currently active Tier0 instance will transition to the OSR method. When the OSR method makes a recursive call, it will invoke the Tier0 method, which will then fairly quickly transition to the OSR version just created. + +## Debugging OSR + +### Seeing which OSR methods are created + +* `DOTNET_DumpJittedMethods=1` will specially mark OSR methods with the inspiring IL offsets. + +For example, running a libraries test with some stressful OSR settings, there ended up being 699 OSR methods jitted out of 160675 total methods. Grepping for OSR in the dump output, the last few lines were: + +``` +Compiling 32408 System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1[WrapperForPoint_3D][System.Text.Json.Serialization.Tests.WrapperForPoint_3D]::OnTryRead, IL size = 850, hash=0x5a693818 Tier1-OSR @0x5f +Compiling 32411 System.Text.Json.Serialization.Tests.ConverterForPoint3D::Read, IL size = 40, hash=0x294c33b5 Tier1-OSR @0xf +Compiling 32412 System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1[WrapperForPoint_3D][System.Text.Json.Serialization.Tests.WrapperForPoint_3D]::OnTryWrite, IL size = 757, hash=0x1ed8b727 Tier1-OSR @0x60 +Compiling 32629 System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1[KeyValuePair`2][System.Collections.Generic.KeyValuePair`2[System.__Canon,System.__Canon]]::ReadConstructorArgumentsWithContinuation, IL size = 192, hash=0x7ab2e686 Tier1-OSR @0x0 +Compiling 32655 System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1[Point_3D_Struct][System.Text.Json.Serialization.Tests.Point_3D_Struct]::ReadConstructorArgumentsWithContinuation, IL size = 192, hash=0xb37dcd36 Tier1-OSR @0x0 +``` +Here the annotations like `@0x5f` tell you the IL offset for the particular OSR method. + +As an aside, seeing patchpoints at offset `@0x0` is a pretty clear indication that the example was run with random patchpoints enabled, as IL offset 0 is rarely the start of a loop. + +Also note that an OSR method will always be invoked immediately after it is jitted. So each of the OSR methods above was executed at least once. + +### Controlling which methods are OSR Eligible + +* `DOTNET_TC_QuickJitForLoops=0` -- no methods are OSR eligible, all get switched to optimized +* `DOTNET_TC_OnStackReplacement=0` -- no methods are OSR eligible, all get jitted at Tier0 +* `DOTNET_JitEnableOsrRange=...` -- use method hash to refine which methods are OSR eligible +* `DOTNET_JitEnablePatchpointRange=...` -- use method hash to refine which Tier0 methods get patchpoints + +Binary searching using the `Enable` controls has proven to be a reliable +way to track down issues in OSR codegen. + +On the same example as above, now run with `COMPlus_JitEnableOsrRange=00000000-7FFFFFFF` there were 249 OSR methods created. Methods with hashes outside this range that would have been handled by OSR were instead immediately optimized and bypassed tiering. So you can systematically reduce the set of OSR methods created to try and find the method or methods that are causing a test failure. + +If you are not familiar with range syntax, ranges values are in hex, and entries can be intervals (as above), singletons, or unions of intervals and singletons, eg +``` +COMPlus_JitEnableOsrRange=00000000-3FFFFFFF,067a3f68,F0000000-FFFFFFFF +``` +I find I rarely need to use anything other than a single range. + +### Changing rate at which OSR methods get created + +These config values can alter the runtime policy and cause OSR methods to be created more eagerly or less eagerly: + +* `DOTNET_OSR_HitCount=N` -- alter the number of times the runtime sees helper call at a given offset until +it creates an OSR method. A value of 0 or 1 eagerly creates OSR methods. +* `DOTNET_OSR_CounterBump=N` -- alter the local counter reload value done by the runtime. A low value means +Tier0 methods with patchpoints will call back into the runtime more often. +* `DOTNET_TC_OnStackReplacement_InitialCounter=N` -- alter the initial counter value the jit bakes into the Tier0 method. +A low value means the initial call into the runtime will happen more quickly. + +Note setting all 3 of these to 0 or 1 will cause OSR methods to be +created the first time a patchpoint is hit. + +If a method has multiple (say two) patchpoints, it may require some +fiddling with these settings to ensure that both OSR versions get +created in a given run. + +### Tracing Runtime Policy + +Setting + +* `DOTNET_LogEnable=1` +* `DOTNET_LogFacility=0x00400000` +* `DOTNET_LogLevel=5` +* and say `DOTNET_LogToConsole=1` + +will log runtime behavior from calls to `CORINFO_HELP_PATCHPOINT` from Tier0 methods. + +For example: +``` +TID 4bdc2: Jit_Patchpoint: patchpoint [17] (0x0000FFFF1E5F3BB8) hit 1 in Method=0x0000FFFF1EAD9130M (Xunit.JsonDeserializer::DeserializeInternal) [il offset 45] (limit 2) +TID 4bdc2: Jit_Patchpoint: patchpoint [17] (0x0000FFFF1E5F3BB8) TRIGGER at count 2 +TID 4bdc2: JitPatchpointWorker: creating OSR version of Method=0x0000FFFF1EAD9130M (Xunit.JsonDeserializer::DeserializeInternal) at offset 45 +TID 4bdc2: Jit_Patchpoint: patchpoint [17] (0x0000FFFF1E5F3BB8) TRANSITION to ip 0x0000FFFF1E5F6820 +TID 4bdc2: Jit_Patchpoint: patchpoint [18] (0x0000FFFF1E5F6BE0) hit 1 in Method=0x0000FFFF1EB03B58M (Xunit.JsonBoolean::.ctor) [il offset 0] (limit 2) +TID 4bdc2: Jit_Patchpoint: patchpoint [18] (0x0000FFFF1E5F6BE0) TRIGGER at count 2 +TID 4bdc2: JitPatchpointWorker: creating OSR version of Method=0x0000FFFF1EB03B58M (Xunit.JsonBoolean::.ctor) at offset 0 +TID 4bdc2: Jit_Patchpoint: patchpoint [18] (0x0000FFFF1E5F6BE0) TRANSITION to ip 0x0000FFFF1E5F6D00 +``` +Here the number in brackets `[17]` is the number of distinct patchpoints that have called the runtime helper; from the runtime side this serve as a sort of patchpoint ID. + +A `hit` is just a call from an Tier0 method to the helper. A `TRIGGER` is a hit that now has reached the `DOTNET_OSR_HitCount` limit, and at this point an OSR method is created. A `TRANSITION` is the transition of control from the Tier0 method to the OSR method. + +You can use the following config settings to further alter runtime policy: +* `DOTNET_OSR_LowId` +* `DOTNET_OSR_HighId` +These collectively form an inclusive range describing which patchpoint IDs will +be allowed to `TRIGGER` (and therefore `TRANSITION`). + +So you can also use this to control which OSR methods are created by the runtime, without altering JIT behavior. + +### Changing where patchpoints are placed in Tier0 code + +* `DOTNET_JitOffsetOnStackReplacement=offset` -- only place patchpoints at given IL offset (and if stack empty) +* `DOTNET_JitRandomOnStackReplacement=val` -- in addition to normal OSR patchpoints, place patchpoints randomly + at stack empty points at the starts of non-handler blocks (value is likelihood, in hex, so 0 will not add any extra, 0x64 will +add as many extra as possible) + +The latter is used by OSR stress (in conjunction with low values for +the policy config) to create large numbers of OSR methods. + +### Controlling what gets dumped + +Enabling jit dumps via name or hash can lead to multiple jit +compilations being dumped: one for Tier0, one for each OSR method, and +one for Tier1). You can control this via: + +* `DOTNET_JitDumpTier0=0` -- suppress dumping all Tier0 jit requests +* `DOTNET_JitDumpAtOSROffset=N` -- only dump OSR jit requests at indicated IL offset + +### Observing OSR from ETW + +OSR methods are marked specially in the ETW MethodJitting events. This +value is not yet parsed in tracevent/perfview/SOS. + +In SOS, OSR version of methods are currently marked as "unknown tier". + +### OSR when Debugging + +When single-stepping at source level through Tier0 code with +patchpoints, the transition to OSR will happen behind the scenes. + +Because OSR code is optimized and Tier0 code is not, you may see a +sudden degradation in what the debugger displays if you step at the +exact point the OSR transition happens. Breakpoints applied at Tier0 +will be reapplied to the OSR method, though they may not "take" if the +source to IL to native mapping information is missing. + +If you step at assembly level you can see the invocation of the +patchpoint helper, etc. + +OSR methods show up normally in the stack, unless execution is paused +in the OSR epilog (working on this). You will only see one entry for +a Tier0 method that's transitioned to an OSR method. + +## OSR and Performance + +As noted above, the combination of `QJFL=1` and `OSR=1` will typically provide better startup and comparable of better steady-state. But it's also possible +to spend considerable time in OSR methods (eg the all-in-`Main` benchmark). + +Generally speaking the performance of an OSR method should be comparable to the equivalent Tier1 method. In practice we see variations of +/- 20% or so. There are a number or reasons for this: +* OSR methods are often a subset of the full Tier1 method, and in many cases just comprise one loop. The JIT can often generate much better code for a single loop in isolation than a single loop in a more complex method. +* A few optimizations are disabled in OSR methods, notably struct promotion. +* OSR methods may only see fractional PGO data (as parts of the Tier0 method may not have executed yet). The JIT doesn't cope very well yet with this sort of partial PGO coverage. + +### Impact on BenchmarkDotNet Results + +BenchmarkDotNet (BDN) typically does a pretty good job of ensuring that measurements are made on the most optimized version of a method. Usually this is the Tier1 version. As such, we don't expect to see OSR have much impact on BDN derived results. + +However, one can configure BenchmarkDotNet in ways that make it more likely that it will measure OSR methods, or some combination of OSR and Tier1 -- in particular reducing the number of warmup iterations. By default a method must be called 30 times to be rejitted at Tier1. So if BDN benchmark is run with less than 30 iterations, there's a chance it may not be measuring Tier1 code for all methods. And when OSR is enabled, this will often mean measuring OSR method perf. + +This happens more often with benchmarks that either (a) do a lot of internal looping to boost the elapsed time of a measurement interval, rather than relying on BDN to determine the appropriate iteration strategy, or (b) are very long running, so that BDN determines that it does not need to run many iterations to obtain measurements of "significant" duration (250 ms or so). + +In the performance repo configurations we reduce the number of warmup iterations and have some benchmarks that fall into both categories above. We'll likely need to make some adjustment to these benchmarks to ensure that we're measuring Tier1 code performance. + +## References + +* [OSR Design Document](https://github.com/dotnet/runtime/blob/main/docs/design/features/OnStackReplacement.md). May be a bit dated in places. +* [OSR Next Steps Issue](https://github.com/dotnet/runtime/issues/33658). Has a lot of information on issues encountered during bring-up, current limitations, and ideas for things we might revisit. \ No newline at end of file diff --git a/docs/workflow/building/coreclr/nativeaot.md b/docs/workflow/building/coreclr/nativeaot.md index 3206fc7349c200..155ed05186e7b0 100644 --- a/docs/workflow/building/coreclr/nativeaot.md +++ b/docs/workflow/building/coreclr/nativeaot.md @@ -59,7 +59,7 @@ The workflow looks like this: ## Running tests -If you haven't built the tests yet, run `src\tests\build[.cmd|.sh] nativeaot [Debug|Release] tree nativeaot`. This will build the smoke tests only - they usually suffice to ensure the runtime and compiler is in a workable shape. To build all Pri-0 tests, drop the `tree nativeaot` parameter. The `Debug`/`Release` parameter should match the build configuration you used to build the runtime. +If you haven't built the tests yet, run `src\tests\build.cmd nativeaot [Debug|Release] tree nativeaot` on Windows, or `src/tests/build.sh -nativeaot [Debug|Release] -tree:nativeaot` on Linux. This will build the smoke tests only - they usually suffice to ensure the runtime and compiler is in a workable shape. To build all Pri-0 tests, drop the `tree nativeaot` parameter. The `Debug`/`Release` parameter should match the build configuration you used to build the runtime. To run all the tests that got built, run `src\tests\run.cmd runnativeaottests [Debug|Release]` on Windows, or `src/tests/run.sh --runnativeaottests [Debug|Release]` on Linux. The `Debug`/`Release` flag should match the flag that was passed to `build.cmd` in the previous step. diff --git a/docs/workflow/building/mono/README.md b/docs/workflow/building/mono/README.md index 56c95551f5eba8..602e65d1c90112 100644 --- a/docs/workflow/building/mono/README.md +++ b/docs/workflow/building/mono/README.md @@ -33,6 +33,16 @@ build.cmd mono ``` When the build completes, product binaries will be dropped in the `artifacts\bin\mono\..` folder. +If you need to run library tests or run HelloWorld sample with your change to mono, you want to build mono with this command instead: + +```bash +./build.sh mono+libs.pretest +``` +or on Windows, +```cmd +build.cmd mono+libs.pretest +``` + If you want to skip restoring nuget packages, when only making change to mono, you want to use this command: ```bash ./build.sh mono --build diff --git a/eng/BeforeTargetFrameworkInference.targets b/eng/BeforeTargetFrameworkInference.targets index b82462e1acc1da..60b412845483fe 100644 --- a/eng/BeforeTargetFrameworkInference.targets +++ b/eng/BeforeTargetFrameworkInference.targets @@ -1,20 +1,5 @@ - - <_OriginalTargetFramework>$(TargetFramework) - $(TargetFramework.SubString($([MSBuild]::Add($(TargetFramework.IndexOf('-')), 1)))) - - $([System.Text.RegularExpressions.Regex]::Replace('$(TargetFramework)', '$(TargetFrameworkPattern)', '${1}')) - - - - $([MSBuild]::NormalizeDirectory('$(BaseIntermediateOutputPath)', '$(TargetFramework)-$(Configuration)')) - $([MSBuild]::NormalizeDirectory('$(BaseIntermediateOutputPath)', '$(TargetFramework)-$(TargetFrameworkSuffix)-$(Configuration)')) - - $([MSBuild]::NormalizeDirectory('$(BaseOutputPath)', '$(TargetFramework)-$(Configuration)')) - $([MSBuild]::NormalizeDirectory('$(BaseOutputPath)', '$(TargetFramework)-$(TargetFrameworkSuffix)-$(Configuration)')) - - diff --git a/eng/Subsets.props b/eng/Subsets.props index 5ea1ff48e23f4a..de8a2710eb6862 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -37,7 +37,7 @@ clr+libs+host+packs - + <_subset Condition="'$(Subset)' != ''">+$(Subset.ToLowerInvariant())+ <_subset Condition="'$(Subset)' == ''">+$(DefaultSubsets)+ @@ -58,7 +58,7 @@ - clr.native+linuxdac+clr.corelib+clr.tools+clr.nativecorelib+clr.packages+clr.nativeaotlibs+clr.spmi + clr.native+linuxdac+clr.corelib+clr.tools+clr.nativecorelib+clr.packages+clr.nativeaotlibs clr.iltools+clr.packages @@ -101,11 +101,11 @@ - + - - - + + + @@ -117,6 +117,7 @@ + @@ -124,7 +125,7 @@ Description="Packaging of cross OS DAC. Requires all assets needed to be present at a folder specified by $(CrossDacArtifactsDir). See 'Microsoft.CrossOsDiag.Private.CoreCLR.proj' for details." /> - + @@ -134,14 +135,14 @@ - + - + @@ -150,7 +151,7 @@ - + @@ -249,6 +250,9 @@ + + + - + https://github.com/dotnet/icu - 80a658fa6aa6601d67bfe5a294e0d1b7e1184a5c + cd095b0fb4c6f8adca9e44ef17346b3e13a73a7c https://github.com/dotnet/msquic a7213b4676c1803bb251771291a525482d42e511 - + https://github.com/dotnet/emsdk - aaa56a6622c4991cf65d553250af3c0ade1320bc + 8f6606fae08ffa42b025dc42ebe2eea91db3a242 https://github.com/dotnet/wcf @@ -50,77 +50,77 @@ - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 https://github.com/microsoft/vstest @@ -170,117 +170,117 @@ https://github.com/dotnet/runtime-assets 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7 - + https://github.com/dotnet/llvm-project - 44adf6c047663fe20c388bfb769e18dd3c91f7e0 + 20080e62c2ea6ed059be57b88268dd8cd28604e6 - + https://github.com/dotnet/llvm-project - 44adf6c047663fe20c388bfb769e18dd3c91f7e0 + 20080e62c2ea6ed059be57b88268dd8cd28604e6 - + https://github.com/dotnet/llvm-project - 44adf6c047663fe20c388bfb769e18dd3c91f7e0 + 20080e62c2ea6ed059be57b88268dd8cd28604e6 - + https://github.com/dotnet/llvm-project - 44adf6c047663fe20c388bfb769e18dd3c91f7e0 + 20080e62c2ea6ed059be57b88268dd8cd28604e6 - + https://github.com/dotnet/llvm-project - 44adf6c047663fe20c388bfb769e18dd3c91f7e0 + 20080e62c2ea6ed059be57b88268dd8cd28604e6 - + https://github.com/dotnet/llvm-project - 44adf6c047663fe20c388bfb769e18dd3c91f7e0 + 20080e62c2ea6ed059be57b88268dd8cd28604e6 - + https://github.com/dotnet/llvm-project - 44adf6c047663fe20c388bfb769e18dd3c91f7e0 + 20080e62c2ea6ed059be57b88268dd8cd28604e6 - + https://github.com/dotnet/llvm-project - 44adf6c047663fe20c388bfb769e18dd3c91f7e0 + 20080e62c2ea6ed059be57b88268dd8cd28604e6 - + https://github.com/dotnet/runtime - 09ff1acdad2e7789908b5db9bb89896144c13042 + bc6d349ecd72eec162f0532e6b6218fdbaa07ddb - + https://github.com/dotnet/runtime - 09ff1acdad2e7789908b5db9bb89896144c13042 + bc6d349ecd72eec162f0532e6b6218fdbaa07ddb - + https://github.com/dotnet/runtime - 09ff1acdad2e7789908b5db9bb89896144c13042 + bc6d349ecd72eec162f0532e6b6218fdbaa07ddb - + https://github.com/dotnet/runtime - 09ff1acdad2e7789908b5db9bb89896144c13042 + bc6d349ecd72eec162f0532e6b6218fdbaa07ddb - + https://github.com/dotnet/runtime - 09ff1acdad2e7789908b5db9bb89896144c13042 + bc6d349ecd72eec162f0532e6b6218fdbaa07ddb - + https://github.com/dotnet/runtime - 09ff1acdad2e7789908b5db9bb89896144c13042 + bc6d349ecd72eec162f0532e6b6218fdbaa07ddb - + https://github.com/dotnet/runtime - 09ff1acdad2e7789908b5db9bb89896144c13042 + bc6d349ecd72eec162f0532e6b6218fdbaa07ddb - + https://github.com/dotnet/runtime - 09ff1acdad2e7789908b5db9bb89896144c13042 + bc6d349ecd72eec162f0532e6b6218fdbaa07ddb - + https://github.com/dotnet/linker - e485816b48273d03bd6266a64dad9bea97f861d5 + 3f704bb49eb2fb2847ceaecfbabe8d5f3e0c86c9 - + https://github.com/dotnet/xharness - 0137095821e2e5a9e030d97248503387b8d72a18 + 4d24e26939bf0770047cd59299235cf6caa86cdb - + https://github.com/dotnet/xharness - 0137095821e2e5a9e030d97248503387b8d72a18 + 4d24e26939bf0770047cd59299235cf6caa86cdb - + https://github.com/dotnet/xharness - 0137095821e2e5a9e030d97248503387b8d72a18 + 4d24e26939bf0770047cd59299235cf6caa86cdb - + https://github.com/dotnet/arcade - 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9 + 4d6406fa2e84c8516a338694be3a4097e6e1f104 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 91d6b3c1f51888d166701510189505f35714665c + 47c55c3cf08885d691aa9d581d40310fe448c1ea - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 91d6b3c1f51888d166701510189505f35714665c + 47c55c3cf08885d691aa9d581d40310fe448c1ea - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 91d6b3c1f51888d166701510189505f35714665c + 47c55c3cf08885d691aa9d581d40310fe448c1ea - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 91d6b3c1f51888d166701510189505f35714665c + 47c55c3cf08885d691aa9d581d40310fe448c1ea - + https://github.com/dotnet/hotreload-utils - d3e96c2e8ed4d58de217c44423c9ba3b90333724 + 3d4988f053ae6b9803e76687b02fee3f8a83156c https://github.com/dotnet/runtime-assets 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7 - + https://github.com/dotnet/roslyn-analyzers - f471d3381584f10f9908432e0b2b2b8ef07a0aa6 + 60eb13c44c366205e5a4dec195404477009c41de https://github.com/dotnet/sdk diff --git a/eng/Versions.props b/eng/Versions.props index aae2d08e090181..aef6a22a358d5b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -50,34 +50,35 @@ 3.3.2 4.0.1 4.0.1 - 7.0.0-preview1.22068.2 + 7.0.0-preview1.22102.1 2.0.0-alpha.1.21525.11 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 2.5.1-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 - 7.0.0-beta.22075.6 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 2.5.1-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22102.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 + 7.0.0-beta.22080.1 6.0.0-preview.1.102 - 7.0.0-alpha.1.22073.5 - 7.0.0-alpha.1.22073.5 - 7.0.0-alpha.1.22073.5 + 7.0.0-preview.2.22080.2 + 7.0.0-preview.2.22080.2 + 7.0.0-preview.2.22080.2 3.1.0 - 7.0.0-alpha.1.22073.5 + 7.0.0-preview.2.22080.2 1.0.0-alpha.1.22073.1 1.0.0-alpha.1.22073.1 1.0.0-alpha.1.22073.1 @@ -120,11 +121,11 @@ 5.0.0 5.0.0 4.9.0-rc2.21473.1 - 7.0.0-alpha.1.22073.5 - 7.0.0-alpha.1.22073.5 + 7.0.0-preview.2.22080.2 + 7.0.0-preview.2.22080.2 4.5.4 4.5.0 - 7.0.0-alpha.1.22073.5 + 7.0.0-preview.2.22080.2 7.0.0-beta.22075.1 7.0.0-beta.22075.1 @@ -139,10 +140,10 @@ 7.0.0-beta.22075.1 7.0.0-beta.22075.1 - 1.0.0-prerelease.21577.2 - 1.0.0-prerelease.21577.2 - 1.0.0-prerelease.21577.2 - 1.0.0-prerelease.21577.2 + 1.0.0-prerelease.22078.3 + 1.0.0-prerelease.22078.3 + 1.0.0-prerelease.22078.3 + 1.0.0-prerelease.22078.3 16.9.0-beta1.21055.5 2.0.0-beta1.20253.1 @@ -160,10 +161,10 @@ 1.0.1-prerelease-00006 16.9.0-preview-20201201-01 - 1.0.0-prerelease.22074.1 - 1.0.0-prerelease.22074.1 - 1.0.0-prerelease.22074.1 - 1.0.2-alpha.0.22074.1 + 1.0.0-prerelease.22101.2 + 1.0.0-prerelease.22101.2 + 1.0.0-prerelease.22101.2 + 1.0.2-alpha.0.22081.2 2.4.2-pre.22 0.12.0-pre.20 2.4.2 @@ -177,23 +178,23 @@ 6.0.0-preview-20220104.1 - 7.0.100-1.22063.2 + 7.0.100-1.22081.3 $(MicrosoftNETILLinkTasksVersion) - 7.0.0-preview.2.22074.5 + 7.0.0-preview.2.22101.1 7.0.0-alpha.1.21529.3 - 11.1.0-alpha.1.22074.2 - 11.1.0-alpha.1.22074.2 - 11.1.0-alpha.1.22074.2 - 11.1.0-alpha.1.22074.2 - 11.1.0-alpha.1.22074.2 - 11.1.0-alpha.1.22074.2 - 11.1.0-alpha.1.22074.2 - 11.1.0-alpha.1.22074.2 + 11.1.0-alpha.1.22081.2 + 11.1.0-alpha.1.22081.2 + 11.1.0-alpha.1.22081.2 + 11.1.0-alpha.1.22081.2 + 11.1.0-alpha.1.22081.2 + 11.1.0-alpha.1.22081.2 + 11.1.0-alpha.1.22081.2 + 11.1.0-alpha.1.22081.2 - 7.0.0-alpha.2.22071.3 + 7.0.0-alpha.2.22102.3 $(MicrosoftNETWorkloadEmscriptenManifest70100Version) 1.1.87-gba258badda diff --git a/eng/build.ps1 b/eng/build.ps1 index 83b9e5104d9000..b424add6fdd97e 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -216,10 +216,7 @@ if ($vs) { # Respect the RuntimeConfiguration variable for building inside VS with different runtime configurations $env:RUNTIMECONFIGURATION=$runtimeConfiguration } - - # Restore the solution to workaround https://github.com/dotnet/runtime/issues/32205 - Invoke-Expression "& dotnet restore $vs" - + # Launch Visual Studio with the locally defined environment variables ."$vs" diff --git a/eng/common/internal/NuGet.config b/eng/common/internal/NuGet.config index 769650362f4aa4..19d3d311b166f5 100644 --- a/eng/common/internal/NuGet.config +++ b/eng/common/internal/NuGet.config @@ -2,6 +2,6 @@ - + diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index 7678b94ce740c0..c5c2a9915121b3 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -24,6 +24,7 @@ parameters: enablePublishBuildAssets: false enablePublishTestResults: false enablePublishUsingPipelines: false + disableComponentGovernance: false mergeTestResults: false testRunTitle: '' testResultsFormat: '' @@ -137,6 +138,9 @@ jobs: richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin continueOnError: true + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), ne(parameters.disableComponentGovernance, 'true')) }}: + - task: ComponentGovernanceComponentDetection@0 + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - task: MicroBuildCleanup@1 diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index fe9dfdf720cf8a..d91bf9147116f0 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -38,10 +38,6 @@ jobs: value: ${{ parameters.configuration }} - group: Publish-Build-Assets - group: AzureDevOps-Artifact-Feeds-Pats - # Skip component governance and codesign validation for SDL. These jobs - # create no content. - - name: skipComponentGovernanceDetection - value: true - name: runCodesignValidationInjection value: false diff --git a/eng/common/templates/jobs/jobs.yml b/eng/common/templates/jobs/jobs.yml index 554e71cfc436dd..70d44735ace4a9 100644 --- a/eng/common/templates/jobs/jobs.yml +++ b/eng/common/templates/jobs/jobs.yml @@ -8,6 +8,10 @@ parameters: # Optional: Enable publishing using release pipelines enablePublishUsingPipelines: false + # Optional: Disable component governance detection. In general, component governance + # should be on for all jobs. Use only in the event of issues. + disableComponentGovernance: false + # Optional: Enable running the source-build jobs to build repo from source enableSourceBuild: false diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index c830e6f277606e..1ac7f49a43ca87 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -22,9 +22,5 @@ variables: - name: SymbolToolVersion value: 1.0.1 - # Skip component governance and codesign validation for SDL. These jobs - # create no content. - - name: skipComponentGovernanceDetection - value: true - name: runCodesignValidationInjection value: false diff --git a/eng/fabricbot/Makefile b/eng/fabricbot/Makefile new file mode 100644 index 00000000000000..86b05f747200a6 --- /dev/null +++ b/eng/fabricbot/Makefile @@ -0,0 +1,4 @@ +generate: + node scripts/updateAreaPodConfigs.js + +.DEFAULT_GOAL := generate \ No newline at end of file diff --git a/eng/fabricbot/README.md b/eng/fabricbot/README.md new file mode 100644 index 00000000000000..90f33835768c7f --- /dev/null +++ b/eng/fabricbot/README.md @@ -0,0 +1,17 @@ +# FabricBot scripts + +Contains scripts used for generating FabricBot automation across all our triage boards. Scripts require nodejs to run: + +```bash +$ node scripts/updateAreaPodConfigs.js +``` + +or if your system has `make` + +```bash +$ make +``` + +Running the script will generate JSON configuration files under the `generated/` subfolder. The generated files are being tracked by git to simplify auditing changes of the generator script. When making changes to the generator script, please ensure that you have run the script and have committed the new generated files. + +Please note that the generated files themselves have no impact on live FabricBot configuration. The changes need to be copied manually under the `.github/fabricbot.json` folder at the root of the `runtime` and `dotnet-api-docs` repos. diff --git a/eng/fabricbot/generated/areapods-dotnet-api-docs.json b/eng/fabricbot/generated/areapods-dotnet-api-docs.json new file mode 100644 index 00000000000000..620f3ff8dd8f91 --- /dev/null +++ b/eng/fabricbot/generated/areapods-dotnet-api-docs.json @@ -0,0 +1,4934 @@ +[ + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-Meta" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Jeff - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Eric / Jeff - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Jeff - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Jeff - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Jeff - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.CodeDom" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Configuration" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Reflection" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Reflection.Emit" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Resources" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Threading.Channels" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Threading.Tasks" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Collections" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Linq" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.Json" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Xml" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-DependencyModel" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Caching" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Configuration" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Hosting" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Logging" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Options" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Primitives" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.ComponentModel" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Composition" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-Infrastructure-libraries" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Microsoft.Win32" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Drawing" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Management" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Carlos / Santi - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Carlos / Santi - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-FileSystem" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Console" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.IO" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.IO.Compression" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Linq.Parallel" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Memory" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Adam / David - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Adam / David - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Adam / David - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Adam / David - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Adam / David - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Adam / David - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Adam / David - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Adam / David - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Adam / David - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "isOrgProject": true + } + } + ] + } + } +] \ No newline at end of file diff --git a/eng/fabricbot/generated/areapods-runtime.json b/eng/fabricbot/generated/areapods-runtime.json new file mode 100644 index 00000000000000..ee2a44f79cf3bf --- /dev/null +++ b/eng/fabricbot/generated/areapods-runtime.json @@ -0,0 +1,5534 @@ +[ + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-Meta" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Jeff - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Eric / Jeff - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Jeff - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Jeff - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Jeff - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Meta" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Jeff - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eric / Jeff - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.CodeDom" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Configuration" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Reflection" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Reflection.Emit" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Resources" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Threading.Channels" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Threading.Tasks" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.CodeDom" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Configuration" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Emit" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Reflection.Metadata" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Resources" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.CompilerServices" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.RegularExpressions" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Channels" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Threading.Tasks" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.DirectoryServices" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Buyaa / Jose / Steve - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Buyaa / Jose / Steve - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Collections" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Linq" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.Json" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Xml" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Collections" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Json" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Xml" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-DependencyModel" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Caching" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Configuration" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Hosting" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Logging" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Options" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-Primitives" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.ComponentModel" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Composition" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-DependencyModel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Caching" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Configuration" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-DependencyInjection" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Hosting" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Logging" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Options" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-Primitives" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ComponentModel.Composition" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Composition" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Activity" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Globalization" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Eric / Maryam / Tarek - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Eric / Maryam / Tarek - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-Infrastructure-libraries" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-Microsoft.Win32" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Drawing" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Management" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Carlos / Santi - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Infrastructure-libraries" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Microsoft.Win32" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.EventLog" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.PerformanceCounter" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.TraceSource" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Drawing" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Management" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.ServiceProcess" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Carlos / Santi - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Carlos / Santi - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-Extensions-FileSystem" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Console" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.IO" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.IO.Compression" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Linq.Parallel" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Memory" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Adam / David - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Adam / David - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Adam / David - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Adam / David - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Adam / David - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Adam / David - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Adam / David - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Adam / David - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Adam / David - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-Extensions-FileSystem" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Console" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Diagnostics.Process" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.IO.Compression" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Linq.Parallel" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Memory" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Adam / David - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Adam / David - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Buffers" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Numerics.Tensors" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Runtime.Intrinsics" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Michael / Tanner - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Michael / Tanner - PRs", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + } + ] + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Add new issue to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Needs Further Triage", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Remove relabeled issues", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": [ + { + "name": "addedToMilestone", + "parameters": {} + }, + { + "name": "labelAdded", + "parameters": { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - Issue Triage] Move to Triaged Column", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - Issue Triage", + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - PRs] Add new PR to Board", + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Asn1" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Formats.Cbor" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Security" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encoding" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "area-System.Text.Encodings.Web" + } + } + ] + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "[Area Pod: Jeremy / Levi - PRs] Remove relabeled PRs", + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": "Area Pod: Jeremy / Levi - PRs", + "isOrgProject": true + } + } + ] + } + } +] \ No newline at end of file diff --git a/eng/fabricbot/scripts/updateAreaPodConfigs.js b/eng/fabricbot/scripts/updateAreaPodConfigs.js new file mode 100644 index 00000000000000..682fee443930ab --- /dev/null +++ b/eng/fabricbot/scripts/updateAreaPodConfigs.js @@ -0,0 +1,598 @@ +// Generates FabricBot config for all area pod triage/PR boards +// +// Running the script using node will update the `../generated*Configs.json` files with the new configuration. +// The generated JSON can then be pasted in the `.github/fabricbot.json` file in dotnet/runtime, +// see https://github.com/dotnet/runtime/blob/main/docs/infra/automation.md for more details. + +const path = require('path'); +const fs = require('fs'); + +let generatedRuntimeConfigsFile = path.join(__dirname, '..', 'generated', 'areapods-runtime.json'); +let generatedApiDocsConfigsFile = path.join(__dirname, '..', 'generated', 'areapods-dotnet-api-docs.json'); + +let areaPods = [ + { + "pod": "Eric / Jeff", + "enabled": true, + "areas": [ + "area-Meta" + ] + }, + { + "pod": "Buyaa / Jose / Steve", + "enabled": true, + "areas": [ + "area-System.CodeDom", + "area-System.Configuration", + "area-System.Reflection", + "area-System.Reflection.Emit", + "area-System.Reflection.Metadata", + "area-System.Resources", + "area-System.Runtime.CompilerServices", + "area-System.Text.RegularExpressions", + "area-System.Threading.Channels", + "area-System.Threading.Tasks", + "area-System.DirectoryServices" + ] + }, + { + "pod": "Eirik / Krzysztof / Layomi", + "enabled": true, + "areas": [ + "area-System.Collections", + "area-System.Linq", + "area-System.Text.Json", + "area-System.Xml" + ] + }, + { + "pod": "Eric / Maryam / Tarek", + "enabled": true, + "areas": [ + "area-DependencyModel", + "area-Extensions-Caching", + "area-Extensions-Configuration", + "area-Extensions-DependencyInjection", + "area-Extensions-Hosting", + "area-Extensions-Logging", + "area-Extensions-Options", + "area-Extensions-Primitives", + "area-System.ComponentModel", + "area-System.ComponentModel.Composition", + "area-System.Composition", + "area-System.Diagnostics.Activity", + "area-System.Globalization" + ] + }, + { + "pod": "Carlos / Santi", + "enabled": true, + "areas": [ + "area-Infrastructure-libraries", + "area-Microsoft.Win32", + "area-System.Diagnostics.EventLog", + "area-System.Diagnostics.PerformanceCounter", + "area-System.Diagnostics.TraceSource", + "area-System.Drawing", + "area-System.Management", + "area-System.ServiceProcess" + ] + }, + { + "pod": "Adam / David", + "enabled": true, + "areas": [ + "area-Extensions-FileSystem", + "area-System.Console", + "area-System.Diagnostics.Process", + "area-System.IO", + "area-System.IO.Compression", + "area-System.Linq.Parallel", + "area-System.Memory" + ] + }, + { + "pod": "Michael / Tanner", + "enabled": true, + "areas": [ + "area-System.Buffers", + "area-System.Numerics", + "area-System.Numerics.Tensors", + "area-System.Runtime", + "area-System.Runtime.Intrinsics" + ] + }, + { + "pod": "Jeremy / Levi", + "enabled": true, + "areas": [ + "area-System.Formats.Asn1", + "area-System.Formats.Cbor", + "area-System.Security", + "area-System.Text.Encoding", + "area-System.Text.Encodings.Web" + ] + } +]; + +let areaPodConfig = { + issueTriageRemove: ({pod, areas}) => ({ + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "columnName": "Needs Triage", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": areas.map(area => ({ + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { "label": area } + } + ] + })) + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": `[Area Pod: ${pod} - Issue Triage] Remove relabeled issues`, + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "isOrgProject": true + } + } + ] + } + }), + issueTriageNeedsTriage: ({pod, areas}) => ({ + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": + { + "conditions": + { + "operator": "and", + "operands": + [ + { + "operator": "or", + "operands": + [ + { + "operator": "and", + "operands": + [ + { + "operator": "or", + "operands": areas.map(area => ({ + "name": "hasLabel", + "parameters": { "label": area } + })) + }, + { + "operator": "or", + "operands": + [ + { + "name": "isAction", + "parameters": + { + "action": "reopened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInMilestone", + "parameters": + {} + } + ] + } + ] + } + ] + }, + { + "operator": "or", + "operands": areas.map(area => ({ + "name": "labelAdded", + "parameters": { "label": area } + })) + } + ] + }, + { + "name": "isOpen", + "parameters": + {} + }, + { + "operator": "or", + "operands": + [ + { + "operator": "not", + "operands": + [ + { + "name": "isInProject", + "parameters": + { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": + { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "isOrgProject": true, + "columnName": "Triaged" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": + [ + "issues", + "project_card" + ], + "taskName": `[Area Pod: ${pod} - Issue Triage] Add new issue to Board`, + "actions": + [ + { + "name": "addToProject", + "parameters": + { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }), + issueTriageNeedsFurtherTriage: ({pod, areas}) => ({ + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": + { + "conditions": + { + "operator": "and", + "operands": + [ + { + "operator": "or", + "operands": areas.map(area => ({ + "name": "hasLabel", + "parameters": { "label": area } + })) + }, + { + "operator": "not", + "operands": + [ + { + "name": "isCloseAndComment", + "parameters": + {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "write" + } + } + ] + }, + { + "operator": "or", + "operands": + [ + { + "operator": "not", + "operands": + [ + { + "name": "isInProject", + "parameters": + { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "isOrgProject": true + } + } + ] + }, + { + "name": "isInProjectColumn", + "parameters": + { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": + [ + "issue_comment" + ], + "taskName": `[Area Pod: ${pod} - Issue Triage] Needs Further Triage`, + "actions": + [ + { + "name": "addToProject", + "parameters": + { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "columnName": "Needs Triage", + "isOrgProject": true + } + } + ] + } + }), + issueTriageTriaged: ({pod, areas}) => ({ + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": + { + "conditions": + { + "operator": "and", + "operands": + [ + { + "name": "isInProject", + "parameters": { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "isOrgProject": true + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "columnName": "Triaged" + } + } + ] + }, + { + "operator": "or", + "operands": + [ + { + "name": "addedToMilestone", + "parameters": + {} + }, + { + "name": "labelAdded", + "parameters": + { + "label": "needs-author-action" + } + }, + { + "name": "labelAdded", + "parameters": + { + "label": "api-ready-for-review" + } + }, + { + "name": "isAction", + "parameters": + { + "action": "closed" + } + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": + [ + "issues", + "project_card" + ], + "taskName": `[Area Pod: ${pod} - Issue Triage] Move to Triaged Column`, + "actions": + [ + { + "name": "addToProject", + "parameters": + { + "projectName": `Area Pod: ${pod} - Issue Triage`, + "columnName": "Triaged", + "isOrgProject": true + } + } + ] + } + }), + + /* Pull Requests */ + + pullRequestAdd: ({pod, areas}) => ({ + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "or", + "operands": areas.map(area => ({ + "name": "hasLabel", + "parameters": { "label": area } + })) + }, + { + "operator": "not", + "operands": [ + { + "name": "isInProject", + "parameters": { + "projectName": `Area Pod: ${pod} - PRs`, + "isOrgProject": true + } + } + ] + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": `[Area Pod: ${pod} - PRs] Add new PR to Board`, + "actions": [ + { + "name": "addToProject", + "parameters": { + "projectName": `Area Pod: ${pod} - PRs`, + "columnName": "Needs Champion", + "isOrgProject": true + } + } + ] + } + }), + prRemove: ({pod, areas}) => ({ + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isInProjectColumn", + "parameters": { + "projectName": `Area Pod: ${pod} - PRs`, + "columnName": "Needs Champion", + "isOrgProject": true + } + }, + { + "operator": "and", + "operands": areas.map(area => ({ + "operator": "not", + "operands": [ + { + "name": "hasLabel", + "parameters": { "label": area } + } + ] + })) + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": `[Area Pod: ${pod} - PRs] Remove relabeled PRs`, + "actions": [ + { + "name": "removeFromProject", + "parameters": { + "projectName": `Area Pod: ${pod} - PRs`, + "isOrgProject": true + } + } + ] + } + }) +}; + +// Generate runtime automation +let generatedRuntimeTasks = areaPods + .filter(areaPod => areaPod.enabled) + .flatMap(areaPod => + [ + areaPodConfig.issueTriageNeedsTriage(areaPod), + areaPodConfig.issueTriageNeedsFurtherTriage(areaPod), + areaPodConfig.issueTriageRemove(areaPod), + areaPodConfig.issueTriageTriaged(areaPod), + areaPodConfig.pullRequestAdd(areaPod), + areaPodConfig.prRemove(areaPod), + ]); + +let generatedRuntimeJson = JSON.stringify(generatedRuntimeTasks, null, 2); +fs.writeFileSync(generatedRuntimeConfigsFile, generatedRuntimeJson); +console.log(`Written generated tasks to ${generatedRuntimeConfigsFile}`); + +// Generate dotnet-api-docs automation +let generatedApiDocsTasks = areaPods + .filter(areaPod => areaPod.enabled) + .flatMap(areaPod => + [ + areaPodConfig.issueTriageNeedsTriage(areaPod), + areaPodConfig.issueTriageNeedsFurtherTriage(areaPod), + areaPodConfig.issueTriageRemove(areaPod), + // areaPodConfig.issueTriageTriaged(areaPod), + areaPodConfig.pullRequestAdd(areaPod), + areaPodConfig.prRemove(areaPod), + ]); + +let generatedApiDocsJson = JSON.stringify(generatedApiDocsTasks, null, 2); +fs.writeFileSync(generatedApiDocsConfigsFile, generatedApiDocsJson); +console.log(`Written generated tasks to ${generatedApiDocsConfigsFile}`); diff --git a/eng/illink.targets b/eng/illink.targets index 018075d8b660b5..d88f0862621419 100644 --- a/eng/illink.targets +++ b/eng/illink.targets @@ -200,8 +200,7 @@ + Condition="'$(ILLinkTrimAssembly)' == ''"> false diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index aab934c42ae6b6..c2f64bf1abf8a5 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -190,6 +190,7 @@ $(LibrariesNativeArtifactsPath)src\*.c; $(LibrariesNativeArtifactsPath)src\*.js; $(LibrariesNativeArtifactsPath)src\emcc-default.rsp; + $(LibrariesNativeArtifactsPath)src\emcc-link.rsp; $(LibrariesNativeArtifactsPath)src\emcc-props.json;" NativeSubDirectory="src" IsNative="true" /> diff --git a/eng/packaging.targets b/eng/packaging.targets index c305c64dd94090..7a29b7d99273d1 100644 --- a/eng/packaging.targets +++ b/eng/packaging.targets @@ -10,7 +10,7 @@ AddNETStandardCompatErrorFileForPackaging;IncludeAnalyzersInPackage;$(PackDependsOn) AddNETStandardCompatErrorFileForPackaging;IncludeAnalyzersInPackage;$(BeforePack) $(TargetsForTfmSpecificContentInPackage);AddRuntimeSpecificFilesToPackage;IncludePrivateProjectReferencesWithPackAttributeInPackage - false + false true $(MSBuildThisFileDirectory)useSharedDesignerContext.txt @@ -73,7 +73,6 @@ - @@ -96,19 +95,18 @@ - + + Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(TargetPlatformIdentifier)' != ''"> $(TargetDir)$(TargetName).pdb - <_packageTargetRuntime Condition="'$(TargetFrameworkIdentifier)' != '.NETFramework'">$(PackageTargetRuntime) - <_packageTargetRuntime Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">win + <_packageTargetRuntime>$(TargetPlatformIdentifier.ToLowerInvariant().Replace('windows', 'win')) + <_targetFrameworkWithoutSuffix>$(TargetFramework) + <_targetFrameworkWithoutSuffix Condition="$(TargetFramework.Contains('-'))">$(TargetFramework.SubString(0, $(TargetFramework.IndexOf('-')))) @@ -116,10 +114,10 @@ @(BuiltProjectOutputGroupOutput); @(DocumentationProjectOutputGroupOutput)" /> + PackagePath="runtimes/$(_packageTargetRuntime)/$(BuildOutputTargetFolder)/$(_targetFrameworkWithoutSuffix)" /> diff --git a/eng/pipelines/common/evaluate-default-paths.yml b/eng/pipelines/common/evaluate-default-paths.yml index 7b404e2c37b745..bf6fdc7c4d1732 100644 --- a/eng/pipelines/common/evaluate-default-paths.yml +++ b/eng/pipelines/common/evaluate-default-paths.yml @@ -116,6 +116,9 @@ jobs: - src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/* - src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/* - src/mono/mono/* + - eng/testing/scenarios/BuildWasmAppsJobsList.txt + - eng/Version.Details.xml + - src/mono/wasm/emscripten-version.txt - subset: wasmdebuggertests include: - src/mono/wasm/debugger/* diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index 4f0200380bc9f7..d815a72e3511b7 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -53,7 +53,7 @@ jobs: ${{ insert }}: ${{ parameters.jobParameters }} # Linux armv6 -- ${{ if or(containsValue(parameters.platforms, 'Linux_armv6'), or(and(ne(parameters.runtimeFlavor, 'mono'), in(parameters.platformGroup, 'gcstress')), and(eq(parameters.runtimeFlavor, 'mono'), in(parameters.platformGroup, 'all', 'gcstress')))) }}: +- ${{ if containsValue(parameters.platforms, 'Linux_armv6') }}: - template: xplat-setup.yml parameters: jobTemplate: ${{ parameters.jobTemplate }} @@ -303,7 +303,7 @@ jobs: targetRid: browser-wasm platform: Browser_wasm container: - image: ubuntu-18.04-webassembly-20210707133424-12f133e + image: ubuntu-18.04-webassembly-20211208134944-544b18c registry: mcr jobParameters: hostedOs: Linux diff --git a/eng/pipelines/coreclr/perf.yml b/eng/pipelines/coreclr/perf.yml index ec233f348b0ecb..278648bc277afb 100644 --- a/eng/pipelines/coreclr/perf.yml +++ b/eng/pipelines/coreclr/perf.yml @@ -484,7 +484,7 @@ jobs: additionalSetupParameters: '--latestdotnet' logicalmachine: 'perftiger' - # build maui workload packs + # build maui runtime packs - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/common/global-build-job.yml @@ -497,6 +497,8 @@ jobs: - Android_arm64 - MacCatalyst_x64 - iOSSimulator_x64 + - iOS_arm64 + - iOS_arm jobParameters: buildArgs: -s mono+libs+host+packs -c $(_BuildConfig) nameSuffix: Maui_Packs_Mono @@ -521,6 +523,8 @@ jobs: - Build_Android_x64_release_Maui_Packs_Mono - Build_MacCatalyst_x64_release_Maui_Packs_Mono - Build_iOSSimulator_x64_release_Maui_Packs_Mono + - Build_iOS_arm_release_Maui_Packs_Mono + - Build_iOS_arm64_release_Maui_Packs_Mono buildArgs: -s mono -c $(_BuildConfig) nameSuffix: MACiOSAndroidMaui isOfficialBuild: false diff --git a/eng/pipelines/coreclr/superpmi-asmdiffs.yml b/eng/pipelines/coreclr/superpmi-asmdiffs.yml index d8835b40b8133d..e30209172c42bf 100644 --- a/eng/pipelines/coreclr/superpmi-asmdiffs.yml +++ b/eng/pipelines/coreclr/superpmi-asmdiffs.yml @@ -9,6 +9,8 @@ pr: include: - main paths: + # If you are changing these and start including eng/common, adjust the Maestro subscriptions + # so that this build can block dependency auto-updates (this build is currently ignored) include: - src/coreclr/jit/* exclude: diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index 9048e8ed4fe8a2..7ef9a25a2474ca 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -220,7 +220,7 @@ jobs: # Run CoreCLR Tools unit tests - ${{ if eq(parameters.testGroup, 'clrTools') }}: - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.tools $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) -ci -test + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.toolstests $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) -ci -test displayName: Run CoreCLR Tools unit tests # Build native test components diff --git a/eng/pipelines/coreclr/templates/build-perf-maui-apps.yml b/eng/pipelines/coreclr/templates/build-perf-maui-apps.yml index 3940fb596a7368..5ca99a4e844114 100644 --- a/eng/pipelines/coreclr/templates/build-perf-maui-apps.yml +++ b/eng/pipelines/coreclr/templates/build-perf-maui-apps.yml @@ -31,7 +31,7 @@ steps: IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-!(*.symbols).nupkg # Other artifacts to include once they are being built - # IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-*.nupkg + # EX. IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-*.nupkg - task: CopyFiles@2 displayName: Flatten packages @@ -80,6 +80,20 @@ steps: destinationFolder: $(Build.SourcesDirectory)/MauiTesting/ArtifactPacks/Microsoft.NETCore.App.Runtime.Mono.android-x64 overwriteExistingFiles: true cleanDestinationFolder: false + - task: ExtractFiles@1 + displayName: Extract ios-arm runtime + inputs: + archiveFilePatterns: $(Build.SourcesDirectory)/MauiTesting/ArtifactPacks/Microsoft.NETCore.App.Runtime.Mono.ios-arm.*.zip + destinationFolder: $(Build.SourcesDirectory)/MauiTesting/ArtifactPacks/Microsoft.NETCore.App.Runtime.Mono.ios-arm + overwriteExistingFiles: true + cleanDestinationFolder: false + - task: ExtractFiles@1 + displayName: Extract ios-arm64 runtime + inputs: + archiveFilePatterns: $(Build.SourcesDirectory)/MauiTesting/ArtifactPacks/Microsoft.NETCore.App.Runtime.Mono.ios-arm64.*.zip + destinationFolder: $(Build.SourcesDirectory)/MauiTesting/ArtifactPacks/Microsoft.NETCore.App.Runtime.Mono.ios-arm64 + overwriteExistingFiles: true + cleanDestinationFolder: false - task: ExtractFiles@1 displayName: Extract maccatalyst-x64 runtime inputs: @@ -96,14 +110,16 @@ steps: cleanDestinationFolder: false - script: | - curl -o ./rollback.json 'maui.blob.core.windows.net/metadata/rollbacks/main.json' - ./dotnet.sh workload update --from-rollback-file ./rollback.json - ./dotnet.sh workload install maui --skip-manifest-update + curl -o dotnet-install.sh 'https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh' + chmod -R a+rx . + ./dotnet-install.sh --channel 6.0.2xx --quality signed --install-dir . + ./dotnet --info + ./dotnet workload install maui --from-rollback-file https://aka.ms/dotnet/maui/main.json --source https://aka.ms/dotnet6/nuget/index.json --source https://api.nuget.org/v3/index.json displayName: Install MAUI workload workingDirectory: $(Build.SourcesDirectory) - script: | - ./dotnet.sh new maui -n MauiTesting + ./dotnet new maui -n MauiTesting cd MauiTesting cp $(Build.SourcesDirectory)/src/tests/Common/maui/MauiScenario.props ./Directory.Build.props cp $(Build.SourcesDirectory)/src/tests/Common/maui/MauiScenario.targets ./Directory.Build.targets @@ -112,21 +128,21 @@ steps: - script: | chmod -R a+r . - ../dotnet.sh publish -bl:MauiAndroid.binlog -f net6.0-android -c Release + ../dotnet publish -bl:MauiAndroid.binlog -f net6.0-android -c Release mv ./bin/Release/net6.0-android/com.companyname.MauiTesting-Signed.apk ./MauiAndroidDefault.apk displayName: Build MAUI Android workingDirectory: $(Build.SourcesDirectory)/MauiTesting - script: | chmod -R a+r . - ../dotnet.sh publish -bl:MauiiOS.binlog -f net6.0-ios -c Release + ../dotnet build -bl:MauiiOS.binlog -f net6.0-ios -c Release mv ./bin/Release/net6.0-ios/iossimulator-x64/MauiTesting.app ./MauiiOSDefault.app displayName: Build MAUI iOS workingDirectory: $(Build.SourcesDirectory)/MauiTesting - script: | chmod -R a+r . - ../dotnet.sh publish -bl:MauiMacCatalyst.binlog -f net6.0-maccatalyst -c Release + ../dotnet publish -bl:MauiMacCatalyst.binlog -f net6.0-maccatalyst -c Release mv ./bin/Release/net6.0-maccatalyst/maccatalyst-x64/MauiTesting.app ./MauiMacCatalystDefault.app displayName: Build MAUI MacCatalyst workingDirectory: $(Build.SourcesDirectory)/MauiTesting diff --git a/eng/pipelines/coreclr/templates/build-perf-sample-apps.yml b/eng/pipelines/coreclr/templates/build-perf-sample-apps.yml index 6e8ace4e7935c2..57d99f231c5f82 100644 --- a/eng/pipelines/coreclr/templates/build-perf-sample-apps.yml +++ b/eng/pipelines/coreclr/templates/build-perf-sample-apps.yml @@ -35,19 +35,6 @@ steps: - script: rm -r -f $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp workingDirectory: $(Build.SourcesDirectory)/artifacts/bin displayName: clean bindir - - script: make run MONO_ARCH=arm64 DEPLOY_AND_RUN=false RUNTIME_COMPONENTS=diagnostics_tracing - workingDirectory: $(Build.SourcesDirectory)/src/mono/sample/Android - displayName: Build HelloAndroid sample app - - script: mv $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/publish/apk/bin/HelloAndroid.apk $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/publish/apk/bin/HelloAndroidWithDiag.apk - - template: /eng/pipelines/common/upload-artifact-step.yml - parameters: - rootFolder: $(Build.SourcesDirectory)/artifacts/bin/AndroidSampleApp/arm64/Release/android-arm64/publish/apk/bin/HelloAndroidWithDiag.apk - includeRootFolder: true - displayName: Android Mono Artifacts With Diag - artifactName: AndroidMonoWithDiagarm64 - archiveExtension: '.tar.gz' - archiveType: tar - tarCompression: gz - ${{ if eq(parameters.osGroup, 'iOS') }}: - script: make build-appbundle TARGET=iOS MONO_ARCH=arm64 MONO_CONFIG=Release AOT=True USE_LLVM=False DEPLOY_AND_RUN=false diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index 0b2e6f7f80ed2a..0c3151159daecd 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -29,7 +29,7 @@ jobs: # iOS/tvOS simulator x64/x86 - ${{ if in(parameters.platform, 'iOSSimulator_x64', 'tvOSSimulator_x64') }}: - - OSX.1015.Amd64.Open + - OSX.1200.Amd64.Open # Android arm64 - ${{ if in(parameters.platform, 'Android_arm64') }}: @@ -106,17 +106,16 @@ jobs: # OSX arm64 - ${{ if eq(parameters.platform, 'OSX_arm64') }}: - ${{ if and(eq(variables['System.TeamProject'], 'public'), in(parameters.jobParameters.helixQueueGroup, 'pr', 'ci', 'libraries')) }}: - - OSX.1100.ARM64.Open + - OSX.1200.ARM64.Open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - OSX.1100.ARM64 + - OSX.1200.ARM64 # OSX x64 - ${{ if eq(parameters.platform, 'OSX_x64') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - OSX.1014.Amd64.Open + - OSX.1200.Amd64.Open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - OSX.1014.Amd64 - - OSX.1015.Amd64 + - OSX.1200.Amd64 # windows x64 - ${{ if eq(parameters.platform, 'windows_x64') }}: diff --git a/eng/pipelines/coreclr/templates/perf-job.yml b/eng/pipelines/coreclr/templates/perf-job.yml index 627d42fd7add18..18912fe315115f 100644 --- a/eng/pipelines/coreclr/templates/perf-job.yml +++ b/eng/pipelines/coreclr/templates/perf-job.yml @@ -166,13 +166,6 @@ jobs: artifactFileName: 'MauiAndroidApp.tar.gz' artifactName: 'MauiAndroidApp' displayName: 'Maui Android App' - - template: /eng/pipelines/common/download-artifact-step.yml - parameters: - unpackFolder: $(Build.SourcesDirectory)/androidHelloWorldWithDiag - cleanUnpackFolder: false - artifactFileName: 'AndroidMonoWithDiagarm64.tar.gz' - artifactName: 'AndroidMonoWithDiagarm64' - displayName: 'Mono Android Diagnostic Helloworld' # Download iOSMono tests and MauiiOS/MacCatalyst - ${{ if eq(parameters.runtimeType, 'iOSMono') }}: diff --git a/eng/pipelines/libraries/enterprise/linux.yml b/eng/pipelines/libraries/enterprise/linux.yml index aa2ccee679549e..fdf003536a6116 100644 --- a/eng/pipelines/libraries/enterprise/linux.yml +++ b/eng/pipelines/libraries/enterprise/linux.yml @@ -10,6 +10,8 @@ pr: - release/*.* paths: + # If you are changing these and start including eng/common, adjust the Maestro subscriptions + # so that this build can block dependency auto-updates (this build is currently ignored) include: - eng/pipelines/libraries/enterprise/* - src/libraries/Common/src/System/Net/* diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index f82e09c9e0a124..b76b762ebc3bb0 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -91,14 +91,11 @@ jobs: # OSX arm64 - ${{ if eq(parameters.platform, 'OSX_arm64') }}: - - OSX.1100.ARM64.Open + - OSX.1200.ARM64.Open # OSX x64 - ${{ if eq(parameters.platform, 'OSX_x64') }}: - - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - - OSX.1014.Amd64.Open - - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - - OSX.1015.Amd64.Open + - OSX.1200.Amd64.Open # Android - ${{ if in(parameters.platform, 'Android_x86', 'Android_x64') }}: @@ -108,11 +105,11 @@ jobs: # iOS Simulator/Mac Catalyst arm64 - ${{ if in(parameters.platform, 'MacCatalyst_arm64', 'iOSSimulator_arm64') }}: - - OSX.1100.ARM64.Open + - OSX.1200.ARM64.Open # iOS/tvOS simulator x64/x86 & MacCatalyst x64 - ${{ if in(parameters.platform, 'iOSSimulator_x64', 'iOSSimulator_x86', 'tvOSSimulator_x64', 'MacCatalyst_x64') }}: - - OSX.1015.Amd64.Open + - OSX.1200.Amd64.Open # iOS devices - ${{ if in(parameters.platform, 'iOS_arm64') }}: @@ -129,26 +126,26 @@ jobs: # libraries on mono outerloop - ${{ if and(eq(parameters.jobParameters.testScope, 'outerloop'), eq(parameters.jobParameters.runtimeFlavor, 'mono')) }}: - Windows.81.Amd64.Open - - Windows.10.Amd64.Server19H1.Open + - Windows.Amd64.Server2022.Open # libraries on coreclr (outerloop and innerloop), or libraries on mono innerloop - ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}: - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - Windows.10.Amd64.ServerRS5.Open - ${{ if ne(parameters.jobParameters.testScope, 'outerloop') }}: - - Windows.10.Amd64.Server19H1.Open - - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h1.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-amd64-20200904200251-272704c + - Windows.Amd64.Server2022.Open + - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h2.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-amd64-20200904200251-272704c - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - Windows.81.Amd64.Open - Windows.10.Amd64.Server19H1.ES.Open - Windows.11.Amd64.ClientPre.Open - ${{ if eq(parameters.jobParameters.testScope, 'outerloop') }}: - - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h1.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-amd64-20200904200251-272704c + - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h2.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-amd64-20200904200251-272704c - ${{ if ne(parameters.jobParameters.runtimeFlavor, 'mono') }}: - (Windows.Nano.1809.Amd64.Open)windows.10.amd64.serverrs5.open@mcr.microsoft.com/dotnet-buildtools/prereqs:nanoserver-1809-helix-amd64-08e8e40-20200107182504 # .NETFramework - ${{ if eq(parameters.jobParameters.framework, 'net48') }}: - - Windows.10.Amd64.Client19H1.Open + - Windows.10.Amd64.Client21H1.Open # windows x86 - ${{ if eq(parameters.platform, 'windows_x86') }}: @@ -162,14 +159,14 @@ jobs: - ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}: - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - Windows.10.Amd64.ServerRS5.Open - - Windows.10.Amd64.Server19H1.Open + - Windows.10.Amd64.Server20H2.Open - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}: - Windows.10.Amd64.Server19H1.ES.Open - Windows.7.Amd64.Open # .NETFramework - ${{ if eq(parameters.jobParameters.framework, 'net48') }}: - - Windows.10.Amd64.Client19H1.Open + - Windows.10.Amd64.Client21H1.Open # windows arm - ${{ if eq(parameters.platform, 'windows_arm') }}: @@ -185,6 +182,6 @@ jobs: # WebAssembly windows - ${{ if eq(parameters.platform, 'Browser_wasm_win') }}: - - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h1.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-webassembly-amd64-20210702131541-6837048 + - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h2.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-webassembly-amd64-20211208140215-544b18c ${{ insert }}: ${{ parameters.jobParameters }} diff --git a/eng/pipelines/mono/templates/workloads-build.yml b/eng/pipelines/mono/templates/workloads-build.yml index a6b6e759306880..0b6e057e8222d9 100644 --- a/eng/pipelines/mono/templates/workloads-build.yml +++ b/eng/pipelines/mono/templates/workloads-build.yml @@ -65,6 +65,7 @@ jobs: IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.MonoTargets.Sdk*.nupkg IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.MonoAOTCompiler.Task*.nupkg IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Sdk*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Templates*.nupkg - task: CopyFiles@2 displayName: Flatten packages diff --git a/eng/pipelines/runtime-extra-platforms.yml b/eng/pipelines/runtime-extra-platforms.yml index a0642f4ab521c7..729a0187ba562b 100644 --- a/eng/pipelines/runtime-extra-platforms.yml +++ b/eng/pipelines/runtime-extra-platforms.yml @@ -118,89 +118,6 @@ jobs: #### MONO LEGS -# -# Build the whole product using Mono and run libraries tests, for Wasm.Build.Tests -# -- template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml - buildConfig: Release - runtimeFlavor: mono - platforms: - # BuildWasmApps should only happen on the extra platforms build as we already have coverage for this build on PRs. - - Browser_wasm - - Browser_wasm_win - variables: - # map dependencies variables to local variables - - name: wasmbuildtestsContainsChange - value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'] ] - jobParameters: - isExtraPlatforms: ${{ variables.isExtraPlatformsBuild }} - testGroup: innerloop - nameSuffix: WasmBuildTests - buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmBuildTests=true /p:TestAssemblies=false /p:BrowserHost=$(_hostedOs) - timeoutInMinutes: 180 - condition: >- - or( - eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'], true), - eq(variables['isRollingBuild'], true)) - # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig)_$(_hostedOs) - extraHelixArguments: /p:BrowserHost=$(_hostedOs) - scenarios: - - buildwasmapps - condition: >- - or( - eq(variables['wasmbuildtestsContainsChange'], true), - eq(variables['isRollingBuild'], true)) - -# -# Build Browser_wasm, on windows, run console and browser tests -# -- template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml - buildConfig: release - runtimeFlavor: mono - platforms: - - Browser_wasm_win - variables: - # map dependencies variables to local variables - - name: librariesContainsChange - value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ] - - name: monoContainsChange - value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ] - jobParameters: - testGroup: innerloop - nameSuffix: LibraryTests - buildArgs: -subset mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=windows - timeoutInMinutes: 180 - condition: >- - or( - eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), - eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true), - eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), - eq(variables['isRollingBuild'], true)) - # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Windows_wasm_$(_BuildConfig) - extraHelixArguments: /p:BrowserHost=windows - scenarios: - - normal - - wasmtestonbrowser - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) - # # Build for Browser/wasm, with EnableAggressiveTrimming=true # @@ -238,11 +155,6 @@ jobs: extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true $(_runSmokeTestsOnlyArg) scenarios: - normal - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) # # Build for Browser/wasm with RunAOTCompilation=true @@ -282,11 +194,6 @@ jobs: extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true $(_runSmokeTestsOnlyArg) /p:BrowserHost=$(_hostedOs) scenarios: - normal - condition: >- - or( - eq(variables['librariesContainsChange'], true), - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) # # Build the whole product using Mono and run libraries tests @@ -415,32 +322,34 @@ jobs: runtimeFlavor: mono platforms: - Browser_wasm + - Browser_wasm_win variables: # map dependencies variables to local variables + - name: librariesContainsChange + value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ] - name: monoContainsChange value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ] jobParameters: testGroup: innerloop - nameSuffix: AllSubsets_Mono - buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true + nameSuffix: LibraryTests + buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=$(_hostedOs) timeoutInMinutes: 180 condition: >- or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), eq(variables['isRollingBuild'], true)) # extra steps, run tests extraStepsTemplate: /eng/pipelines/libraries/helix.yml extraStepsParameters: creator: dotnet-bot testRunNamePrefixSuffix: Mono_$(_BuildConfig) + extraHelixArguments: /p:BrowserHost=$(_hostedOs) scenarios: - normal - WasmTestOnBrowser - WasmTestOnNodeJs - condition: >- - or( - eq(variables['monoContainsChange'], true), - eq(variables['isRollingBuild'], true)) # # Build the whole product using Mono and run runtime tests @@ -480,67 +389,6 @@ jobs: eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true), eq(variables['isRollingBuild'], true)) -# Wasm debugger tests -- template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml - buildConfig: Release - runtimeFlavor: mono - platforms: - - Browser_wasm - variables: - # map dependencies variables to local variables - - name: wasmdebuggertestsContainsChange - value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'] ] - jobParameters: - testGroup: innerloop - nameSuffix: Mono_DebuggerTests - buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false - timeoutInMinutes: 180 - condition: >- - or( - eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true), - eq(variables['isRollingBuild'], true)) - # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - scenarios: - - wasmdebuggertests - -# Wasm debugger tests - windows -- template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml - buildConfig: Release - runtimeFlavor: mono - platforms: - - Browser_wasm_win - variables: - # map dependencies variables to local variables - - name: wasmdebuggertestsContainsChange - value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'] ] - jobParameters: - testGroup: innerloop - nameSuffix: Mono_DebuggerTests - buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false /p:BrowserHost=windows - timeoutInMinutes: 180 - condition: >- - or( - eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true), - eq(variables['isRollingBuild'], true)) - # extra steps, run tests - extraStepsTemplate: /eng/pipelines/libraries/helix.yml - extraStepsParameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Mono_$(_BuildConfig) - extraHelixArguments: /p:BrowserHost=windows - scenarios: - - wasmdebuggertests - # # Build the whole product using Mono for Android and run runtime tests with Android emulator # diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index c51d639d29f0f2..e8f707ff5e6d58 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -444,7 +444,9 @@ jobs: buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false /p:BrowserHost=windows timeoutInMinutes: 180 condition: >- - eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true) + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true), + eq(variables['isRollingBuild'], true)) # extra steps, run tests extraStepsTemplate: /eng/pipelines/libraries/helix.yml extraStepsParameters: @@ -454,7 +456,7 @@ jobs: scenarios: - wasmdebuggertests -# Wasm debugger tests +# Wasm debugger tests - linux - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/common/global-build-job.yml @@ -473,7 +475,9 @@ jobs: buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false timeoutInMinutes: 180 condition: >- - eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true) + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true), + eq(variables['isRollingBuild'], true)) # extra steps, run tests extraStepsTemplate: /eng/pipelines/libraries/helix.yml extraStepsParameters: diff --git a/eng/slngen.nuget.config b/eng/slngen.nuget.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/eng/slngen.nuget.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/eng/targetframeworksuffix.props b/eng/targetframeworksuffix.props index ccbf1aa2883664..f7074fe3e199f4 100644 --- a/eng/targetframeworksuffix.props +++ b/eng/targetframeworksuffix.props @@ -8,105 +8,91 @@ This is required for platforms not expected to have a version, and we currently omit the version for all platforms. --> 0.0 + $(TargetFramework.SubString($([MSBuild]::Add($(TargetFramework.IndexOf('-')), 1)))) - - $(TargetFrameworkSuffix) + 1.0 - $(TargetFrameworkSuffix),Version=$(TargetPlatformVersion) - + true - win - + true - unix - + true true - linux - + true true true - android - + true true - osx - + true true - maccatalyst - + true true - tvos - + true true - ios - + true true - freebsd - + true true - netbsd - + true true - illumos - + true true - solaris - + true - browser - + true diff --git a/eng/testing/performance/android_scenarios.proj b/eng/testing/performance/android_scenarios.proj index 52af8fa1678dc8..fefff6deeefe08 100644 --- a/eng/testing/performance/android_scenarios.proj +++ b/eng/testing/performance/android_scenarios.proj @@ -49,8 +49,14 @@ $(WorkItemDirectory) - echo on;set XHARNESSPATH=$(XharnessPath);cd $(ScenarioDirectory)helloandroid;copy %HELIX_CORRELATION_PAYLOAD%\HelloAndroidWithDiag.apk .;$(Python) pre.py - $(Python) test.py devicestartup --device-type android --package-path pub\HelloAndroidWithDiag.apk --package-name net.dot.HelloAndroid --exit-code 42 --scenario-name "%(Identity)" + echo on;set XHARNESSPATH=$(XharnessPath);cd $(ScenarioDirectory)helloandroid;copy %HELIX_CORRELATION_PAYLOAD%\HelloAndroid.apk .;$(Python) pre.py + $(Python) test.py devicestartup --device-type android --package-path pub\HelloAndroid.apk --package-name net.dot.HelloAndroid --scenario-name "%(Identity)" + $(Python) post.py + + + $(WorkItemDirectory) + echo on;set XHARNESSPATH=$(XharnessPath);cd $(ScenarioDirectory)mauiandroid;copy %HELIX_CORRELATION_PAYLOAD%\MauiAndroidDefault.apk .;$(Python) pre.py + $(Python) test.py devicestartup --device-type android --package-path pub\MauiAndroidDefault.apk --package-name com.companyname.mauitesting --scenario-name "%(Identity)" $(Python) post.py diff --git a/eng/testing/performance/performance-setup.ps1 b/eng/testing/performance/performance-setup.ps1 index d85325ee1349d5..7f1be6761b5049 100644 --- a/eng/testing/performance/performance-setup.ps1 +++ b/eng/testing/performance/performance-setup.ps1 @@ -148,14 +148,9 @@ if ($AndroidMono) { { mkdir $WorkItemDirectory } - if(Test-Path "$SourceDirectory\androidHelloWorld\HelloAndroid.apk") { - Copy-Item -path "$SourceDirectory\androidHelloWorld\HelloAndroid.apk" $PayloadDirectory -Verbose - } - - if(Test-Path "$SourceDirectory\androidHelloWorldWithDiag\HelloAndroidWithDiag.apk") { - Copy-Item -path "$SourceDirectory\androidHelloWorldWithDiag\HelloAndroidWithDiag.apk" $PayloadDirectory -Verbose - } - Copy-Item -path "$SourceDirectory\MauiAndroidDefault.apk" $PayloadDirectory + + Copy-Item -path "$SourceDirectory\androidHelloWorld\HelloAndroid.apk" $PayloadDirectory -Verbose + Copy-Item -path "$SourceDirectory\MauiAndroidDefault.apk" $PayloadDirectory -Verbose $SetupArguments = $SetupArguments -replace $Architecture, 'arm64' } diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt index 8afeea6cdeeb13..c44096b4b7b476 100644 --- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt +++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt @@ -17,3 +17,4 @@ Wasm.Build.Tests.SatelliteAssembliesTests Wasm.Build.Tests.WasmBuildAppTest Wasm.Build.Tests.WasmNativeDefaultsTests Wasm.Build.Tests.WorkloadTests +Wasm.Build.Tests.WasmTemplateTests diff --git a/eng/testing/scenarios/WasmDebuggerTestsJobsList.txt b/eng/testing/scenarios/WasmDebuggerTestsJobsList.txt index d4ef9dcbfc399b..93917d7b22907d 100644 --- a/eng/testing/scenarios/WasmDebuggerTestsJobsList.txt +++ b/eng/testing/scenarios/WasmDebuggerTestsJobsList.txt @@ -16,3 +16,4 @@ DebuggerTests.PointerTests DebuggerTests.SetVariableValueTests DebuggerTests.MiscTests DebuggerTests.SteppingTests +DebuggerTests.SetNextIpTests diff --git a/eng/testing/tests.props b/eng/testing/tests.props index 3025ab62335049..f23f4cc62e9560 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -24,10 +24,9 @@ - $(NetCoreAppCurrent)-$(Configuration) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner', '$(MobileRunnersDirSuffix)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner', '$(MobileRunnersDirSuffix)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'WasmTestRunner', '$(MobileRunnersDirSuffix)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner', '$(Configuration)', '$(NetCoreAppCurrent)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner', '$(Configuration)', '$(NetCoreAppCurrent)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'WasmTestRunner', '$(Configuration)', '$(NetCoreAppCurrent)')) $(PackageRID) true diff --git a/global.json b/global.json index 43ff763c74d864..cdc6966b29227b 100644 --- a/global.json +++ b/global.json @@ -12,12 +12,11 @@ "python3": "3.7.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "7.0.0-beta.22075.6", - "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22075.6", - "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22075.6", - "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.22075.6", + "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22080.1", + "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22080.1", + "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.22080.1", "Microsoft.Build.NoTargets": "3.1.0", "Microsoft.Build.Traversal": "3.0.23", - "Microsoft.NET.Sdk.IL": "7.0.0-alpha.1.22073.5" + "Microsoft.NET.Sdk.IL": "7.0.0-preview.2.22080.2" } } diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj index 3d21bffd3d24f8..9cbfee4fb88b0b 100644 --- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -309,7 +309,7 @@ causing impactful slowdowns while typing in the Corelib project. --> - + diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.sln b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.sln index 4629497f45f7cc..66c65e680d4693 100644 --- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.sln +++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.sln @@ -6,7 +6,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "S EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "System.Private.CoreLib.Shared", "..\..\libraries\System.Private.CoreLib\src\System.Private.CoreLib.Shared.shproj", "{845C8B26-350B-4E63-BD11-2C8150444E28}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\..\libraries\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{7196828B-5E00-4BC6-9A1E-492C948E41A3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\..\libraries\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{7196828B-5E00-4BC6-9A1E-492C948E41A3}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs index 9def7541aa4c6a..3e8bd014fb0aa3 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs @@ -32,94 +32,6 @@ namespace System.Reflection.Emit { - // When the user calls AppDomain.DefineDynamicAssembly the loader creates a new InternalAssemblyBuilder. - // This InternalAssemblyBuilder can be retrieved via a call to Assembly.GetAssemblies() by untrusted code. - // In the past, when InternalAssemblyBuilder was AssemblyBuilder, the untrusted user could down cast the - // Assembly to an AssemblyBuilder and emit code with the elevated permissions of the trusted code which - // originally created the AssemblyBuilder via DefineDynamicAssembly. Today, this can no longer happen - // because the Assembly returned via AssemblyGetAssemblies() will be an InternalAssemblyBuilder. - - // Only the caller of DefineDynamicAssembly will get an AssemblyBuilder. - // There is a 1-1 relationship between InternalAssemblyBuilder and AssemblyBuilder. - // AssemblyBuilder is composed of its InternalAssemblyBuilder. - // The AssemblyBuilder data members (e.g. m_foo) were changed to properties which then delegate - // the access to the composed InternalAssemblyBuilder. This way, AssemblyBuilder simply wraps - // InternalAssemblyBuilder and still operates on InternalAssemblyBuilder members. - // This also makes the change transparent to the loader. This is good because most of the complexity - // of Assembly building is in the loader code so not touching that code reduces the chance of - // introducing new bugs. - internal sealed class InternalAssemblyBuilder : RuntimeAssembly - { - private InternalAssemblyBuilder() { } - - public override bool Equals(object? obj) - { - if (obj == null) - { - return false; - } - - if (obj is InternalAssemblyBuilder) - { - return (object)this == obj; - } - - return obj.Equals(this); - } - - public override int GetHashCode() => base.GetHashCode(); - - // Assembly methods that are overridden by AssemblyBuilder should be overridden by InternalAssemblyBuilder too - #region Methods inherited from Assembly - - public override string[] GetManifestResourceNames() - { - throw new NotSupportedException(SR.NotSupported_DynamicAssembly); - } - - [RequiresAssemblyFiles(ThrowingMessageInRAF)] - public override FileStream GetFile(string name) - { - throw new NotSupportedException(SR.NotSupported_DynamicAssembly); - } - - [RequiresAssemblyFiles(ThrowingMessageInRAF)] - public override FileStream[] GetFiles(bool getResourceModules) - { - throw new NotSupportedException(SR.NotSupported_DynamicAssembly); - } - - public override Stream? GetManifestResourceStream(Type type, string name) - { - throw new NotSupportedException(SR.NotSupported_DynamicAssembly); - } - - public override Stream? GetManifestResourceStream(string name) - { - throw new NotSupportedException(SR.NotSupported_DynamicAssembly); - } - - public override ManifestResourceInfo? GetManifestResourceInfo(string resourceName) - { - throw new NotSupportedException(SR.NotSupported_DynamicAssembly); - } - - public override string Location => string.Empty; - - [RequiresAssemblyFiles(ThrowingMessageInRAF)] - public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly); - - [RequiresUnreferencedCode("Types might be removed")] - public override Type[] GetExportedTypes() - { - throw new NotSupportedException(SR.NotSupported_DynamicAssembly); - } - - public override string ImageRuntimeVersion => Assembly.GetExecutingAssembly().ImageRuntimeVersion; - - #endregion - } - public sealed partial class AssemblyBuilder : Assembly { [MethodImpl(MethodImplOptions.InternalCall)] @@ -129,14 +41,14 @@ public sealed partial class AssemblyBuilder : Assembly // This is only valid in the "external" AssemblyBuilder internal AssemblyBuilderData _assemblyData; - private readonly InternalAssemblyBuilder _internalAssemblyBuilder; + private readonly RuntimeAssembly _internalAssembly; private ModuleBuilder _manifestModuleBuilder; // Set to true if the manifest module was returned by code:DefineDynamicModule to the user private bool _isManifestModuleUsedAsDefinedModule; private const string ManifestModuleName = "RefEmit_InMemoryManifestModule"; - internal ModuleBuilder GetModuleBuilder(InternalModuleBuilder module) + internal ModuleBuilder GetModuleBuilder(RuntimeModule module) { Debug.Assert(module != null); Debug.Assert(InternalAssembly == module.Assembly); @@ -155,7 +67,7 @@ internal ModuleBuilder GetModuleBuilder(InternalModuleBuilder module) internal object SyncRoot => InternalAssembly.SyncRoot; - internal InternalAssemblyBuilder InternalAssembly => _internalAssemblyBuilder; + internal RuntimeAssembly InternalAssembly => _internalAssembly; #endregion @@ -190,13 +102,13 @@ internal AssemblyBuilder(AssemblyName name, assemblyAttributes = new List(unsafeAssemblyAttributes); } - Assembly? retAssembly = null; + RuntimeAssembly? retAssembly = null; CreateDynamicAssembly(ObjectHandleOnStack.Create(ref name), new StackCrawlMarkHandle(ref stackMark), (int)access, ObjectHandleOnStack.Create(ref assemblyLoadContext), ObjectHandleOnStack.Create(ref retAssembly)); - _internalAssemblyBuilder = (InternalAssemblyBuilder)retAssembly!; + _internalAssembly = retAssembly!; _assemblyData = new AssemblyBuilderData(access); @@ -216,7 +128,7 @@ internal AssemblyBuilder(AssemblyName name, [MemberNotNull(nameof(_manifestModuleBuilder))] private void InitManifestModule() { - InternalModuleBuilder modBuilder = (InternalModuleBuilder)GetInMemoryAssemblyModule(InternalAssembly); + RuntimeModule modBuilder = (RuntimeModule)GetInMemoryAssemblyModule(InternalAssembly); // Note that this ModuleBuilder cannot be used for RefEmit yet // because it hasn't been initialized. @@ -386,10 +298,9 @@ internal static void CheckContext(params Type?[]? types) } } - public override bool Equals(object? obj) => InternalAssembly.Equals(obj); + public override bool Equals(object? obj) => base.Equals(obj); - // Need a dummy GetHashCode to pair with Equals - public override int GetHashCode() => InternalAssembly.GetHashCode(); + public override int GetHashCode() => base.GetHashCode(); #region ICustomAttributeProvider Members public override object[] GetCustomAttributes(bool inherit) => diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index 0e4741ea643d03..c98d78da4c84bf 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -41,7 +41,7 @@ public sealed class DynamicMethod : MethodInfo // We capture the creation context so that we can do the checks against the same context, // irrespective of when the method gets compiled. Note that the DynamicMethod does not know when // it is ready for use since there is not API which indictates that IL generation has completed. - private static volatile InternalModuleBuilder? s_anonymouslyHostedDynamicMethodsModule; + private static volatile RuntimeModule? s_anonymouslyHostedDynamicMethodsModule; private static readonly object s_anonymouslyHostedDynamicMethodsModuleLock = new object(); // @@ -244,7 +244,7 @@ private static RuntimeModule GetDynamicMethodsModule() null); // this always gets the internal module. - s_anonymouslyHostedDynamicMethodsModule = (InternalModuleBuilder)assembly.ManifestModule!; + s_anonymouslyHostedDynamicMethodsModule = (RuntimeModule)assembly.ManifestModule!; } return s_anonymouslyHostedDynamicMethodsModule; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs index cbe0a7b39dde5b..f1ffa97874925f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs @@ -10,31 +10,6 @@ namespace System.Reflection.Emit { - internal sealed partial class InternalModuleBuilder : RuntimeModule - { - // InternalModuleBuilder should not contain any data members as its reflectbase is the same as Module. - - private InternalModuleBuilder() { } - - public override bool Equals(object? obj) - { - if (obj == null) - { - return false; - } - - if (obj is InternalModuleBuilder) - { - return (object)this == obj; - } - - return obj.Equals(this); - } - - // Need a dummy GetHashCode to pair with Equals - public override int GetHashCode() => base.GetHashCode(); - } - // deliberately not [serializable] public partial class ModuleBuilder : Module { @@ -75,7 +50,7 @@ internal static string UnmangleTypeName(string typeName) // _TypeBuilder contains both TypeBuilder and EnumBuilder objects private Dictionary _typeBuilderDict = null!; internal ModuleBuilderData _moduleData = null!; - internal InternalModuleBuilder _internalModuleBuilder; + internal RuntimeModule _internalModule; // This is the "external" AssemblyBuilder // only the "external" ModuleBuilder has this set private readonly AssemblyBuilder _assemblyBuilder; @@ -85,9 +60,9 @@ internal static string UnmangleTypeName(string typeName) #region Constructor - internal ModuleBuilder(AssemblyBuilder assemblyBuilder, InternalModuleBuilder internalModuleBuilder) + internal ModuleBuilder(AssemblyBuilder assemblyBuilder, RuntimeModule internalModule) { - _internalModuleBuilder = internalModuleBuilder; + _internalModule = internalModule; _assemblyBuilder = assemblyBuilder; } @@ -323,8 +298,7 @@ internal void Init(string strModuleName) #region Module Overrides - // _internalModuleBuilder is null iff this is a "internal" ModuleBuilder - internal InternalModuleBuilder InternalModule => _internalModuleBuilder; + internal RuntimeModule InternalModule => _internalModule; protected override ModuleHandle GetModuleHandleImpl() => new ModuleHandle(InternalModule); @@ -513,10 +487,9 @@ internal SignatureHelper GetMemberRefSignature(MethodBase? method, int cGenericP #endregion - public override bool Equals(object? obj) => InternalModule.Equals(obj); + public override bool Equals(object? obj) => base.Equals(obj); - // Need a dummy GetHashCode to pair with Equals - public override int GetHashCode() => InternalModule.GetHashCode(); + public override int GetHashCode() => base.GetHashCode(); #region ICustomAttributeProvider Members @@ -1127,7 +1100,7 @@ private int GetTypeTokenWorkerNoLock(Type type, bool getGenericDefinition) // the file name of the referenced module. if (refedModuleBuilder == null) { - refedModuleBuilder = ContainingAssemblyBuilder.GetModuleBuilder((InternalModuleBuilder)refedModule); + refedModuleBuilder = ContainingAssemblyBuilder.GetModuleBuilder((RuntimeModule)refedModule); } referencedModuleFileName = refedModuleBuilder._moduleData._moduleName; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index 877c449ad45808..7eed453959c668 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -16,7 +16,7 @@ namespace System.Reflection { - internal partial class RuntimeAssembly : Assembly + internal sealed partial class RuntimeAssembly : Assembly { internal RuntimeAssembly() { throw new NotSupportedException(); } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs index cba7d80fa15b09..e8b52d01d5e0da 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs @@ -9,7 +9,7 @@ namespace System.Reflection { - internal partial class RuntimeModule : Module + internal sealed partial class RuntimeModule : Module { internal RuntimeModule() { throw new NotSupportedException(); } diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp index 2d979c395610e9..ceadbf1af995b4 100644 --- a/src/coreclr/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/gc/unix/gcenv.unix.cpp @@ -946,7 +946,12 @@ static size_t GetLogicalProcessorCacheSizeFromOS() { int64_t cacheSizeFromSysctl = 0; size_t sz = sizeof(cacheSizeFromSysctl); - const bool success = sysctlbyname("hw.l3cachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0 + const bool success = false + // macOS-arm64: Since macOS 12.0, Apple added ".perflevelX." to determinate cache sizes for efficiency + // and performance cores separetely. "perflevel0" stands for "performance" + || sysctlbyname("hw.perflevel0.l2cachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0 + // macOS-arm64: these report cache sizes for efficiency cores only: + || sysctlbyname("hw.l3cachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0 || sysctlbyname("hw.l2cachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0 || sysctlbyname("hw.l1dcachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0; if (success) diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index e544430fa587ba..93459c739f78e8 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -804,7 +804,6 @@ CONFIG_DWORD_INFO(INTERNAL_NestedEhOom, W("NestedEhOom"), 0, "") #define INTERNAL_NoGuiOnAssert_Default 1 RETAIL_CONFIG_DWORD_INFO(INTERNAL_NoGuiOnAssert, W("NoGuiOnAssert"), INTERNAL_NoGuiOnAssert_Default, "") RETAIL_CONFIG_DWORD_INFO(EXTERNAL_NoProcedureSplitting, W("NoProcedureSplitting"), 0, "") -CONFIG_DWORD_INFO(INTERNAL_NoStringInterning, W("NoStringInterning"), 1, "Disallows string interning. I see no value in it anymore.") CONFIG_DWORD_INFO(INTERNAL_PauseOnLoad, W("PauseOnLoad"), 0, "Stops in SystemDomain::init. I think it can be removed.") CONFIG_DWORD_INFO(INTERNAL_PerfAllocsSizeThreshold, W("PerfAllocsSizeThreshold"), 0x3FFFFFFF, "Log facility LF_GCALLOC logs object allocations. This flag controls which ones also log stacktraces. Predates ClrProfiler.") CONFIG_DWORD_INFO(INTERNAL_PerfNumAllocsThreshold, W("PerfNumAllocsThreshold"), 0x3FFFFFFF, "Log facility LF_GCALLOC logs object allocations. This flag controls which ones also log stacktraces. Predates ClrProfiler.") diff --git a/src/coreclr/inc/corhdr.h b/src/coreclr/inc/corhdr.h index 11dd7029884539..b4ea57f811ce14 100644 --- a/src/coreclr/inc/corhdr.h +++ b/src/coreclr/inc/corhdr.h @@ -1683,17 +1683,6 @@ typedef enum CorAttributeTargets #define DEBUGGABLE_ATTRIBUTE_TYPE_NAME "DebuggableAttribute" -// Keep in sync with CompilationRelaxations.cs -typedef enum CompilationRelaxationsEnum -{ - CompilationRelaxations_NoStringInterning = 0x0008, - -} CompilationRelaxationEnum; - -#define COMPILATIONRELAXATIONS_TYPE_W W("System.Runtime.CompilerServices.CompilationRelaxationsAttribute") -#define COMPILATIONRELAXATIONS_TYPE "System.Runtime.CompilerServices.CompilationRelaxationsAttribute" - - // Keep in sync with RuntimeCompatibilityAttribute.cs #define RUNTIMECOMPATIBILITY_TYPE_W W("System.Runtime.CompilerServices.RuntimeCompatibilityAttribute") #define RUNTIMECOMPATIBILITY_TYPE "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute" diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 3bad0df909e9a6..46099e21382b54 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -928,16 +928,6 @@ enum CorInfoInline INLINE_NEVER = -2, // This method should never be inlined, regardless of context }; -enum CorInfoInlineRestrictions -{ - INLINE_RESPECT_BOUNDARY = 0x00000001, // You can inline if there are no calls from the method being inlined - INLINE_NO_CALLEE_LDSTR = 0x00000002, // You can inline only if you guarantee that if inlinee does an ldstr - // inlinee's module will never see that string (by any means). - // This is due to how we implement the NoStringInterningAttribute - // (by reusing the fixup table). - INLINE_SAME_THIS = 0x00000004, // You can inline only if the callee is on the same this reference as caller -}; - enum CorInfoInlineTypeCheck { CORINFO_INLINE_TYPECHECK_NONE = 0x00000000, // It's not okay to compare type's vtable with a native type handle @@ -1997,9 +1987,7 @@ class ICorStaticInfo ) = 0; // Decides if you have any limitations for inlining. If everything's OK, it will return - // INLINE_PASS and will fill out pRestrictions with a mask of restrictions the caller of this - // function must respect. If caller passes pRestrictions = NULL, if there are any restrictions - // INLINE_FAIL will be returned + // INLINE_PASS. // // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls) // @@ -2007,8 +1995,7 @@ class ICorStaticInfo virtual CorInfoInline canInline ( CORINFO_METHOD_HANDLE callerHnd, /* IN */ - CORINFO_METHOD_HANDLE calleeHnd, /* IN */ - uint32_t* pRestrictions /* OUT */ + CORINFO_METHOD_HANDLE calleeHnd /* IN */ ) = 0; // Reports whether or not a method can be inlined, and why. canInline is responsible for reporting all diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 21236cc92cb17d..132707a4ef485d 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -42,8 +42,7 @@ bool getMethodInfo( CorInfoInline canInline( CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE calleeHnd, - uint32_t* pRestrictions) override; + CORINFO_METHOD_HANDLE calleeHnd) override; void reportInliningDecision( CORINFO_METHOD_HANDLE inlinerHnd, diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index e7b8884419e5a6..66de16f77a0ca5 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED -constexpr GUID JITEEVersionIdentifier = { /* 323185e9-208a-4b35-a413-23f9aac2d5f7 */ - 0x323185e9, - 0x208a, - 0x4b35, - {0xa4, 0x13, 0x23, 0xf9, 0xaa, 0xc2, 0xd5, 0xf7} +constexpr GUID JITEEVersionIdentifier = { /* ccb0c159-04b3-47f6-993e-79114c9cbef8 */ + 0xccb0c159, + 0x04b3, + 0x47f6, + {0x99, 0x3e, 0x79, 0x11, 0x4c, 0x9c, 0xbe, 0xf8} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/inc/sigparser.h b/src/coreclr/inc/sigparser.h index 1e861c4cd3edf8..b9b79e951e40b8 100644 --- a/src/coreclr/inc/sigparser.h +++ b/src/coreclr/inc/sigparser.h @@ -864,6 +864,21 @@ class CorTypeInfo return (GetGCType_NoThrow(type) == TYPE_GC_REF); } + static BOOL IsByRef(CorElementType type) + { + WRAPPER_NO_CONTRACT; + SUPPORTS_DAC; + + return (GetGCType(type) == TYPE_GC_BYREF); + } + static BOOL IsByRef_NoThrow(CorElementType type) + { + WRAPPER_NO_CONTRACT; + SUPPORTS_DAC; + + return (GetGCType_NoThrow(type) == TYPE_GC_BYREF); + } + FORCEINLINE static BOOL IsGenericVariable(CorElementType type) { WRAPPER_NO_CONTRACT; diff --git a/src/coreclr/inc/stresslog.h b/src/coreclr/inc/stresslog.h index 4ee3acaeb8bb6c..35381a17cbb310 100644 --- a/src/coreclr/inc/stresslog.h +++ b/src/coreclr/inc/stresslog.h @@ -740,6 +740,7 @@ class ThreadStressLog { #if defined(MEMORY_MAPPED_STRESSLOG) && !defined(STRESS_LOG_ANALYZER) void* __cdecl operator new(size_t n, const NoThrow&) NOEXCEPT; + void __cdecl operator delete (void * chunk); #endif ~ThreadStressLog () diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt index ebca7e65daaac7..0534375b821af1 100644 --- a/src/coreclr/jit/CMakeLists.txt +++ b/src/coreclr/jit/CMakeLists.txt @@ -104,6 +104,7 @@ set( JIT_SOURCES fgprofile.cpp fgstmt.cpp flowgraph.cpp + forwardsub.cpp gcdecode.cpp gcencode.cpp gcinfo.cpp diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index 6de2cf03a26b1b..2cd1c0d4235d9a 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -61,11 +61,10 @@ bool WrapICorJitInfo::getMethodInfo( CorInfoInline WrapICorJitInfo::canInline( CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE calleeHnd, - uint32_t* pRestrictions) + CORINFO_METHOD_HANDLE calleeHnd) { API_ENTER(canInline); - CorInfoInline temp = wrapHnd->canInline(callerHnd, calleeHnd, pRestrictions); + CorInfoInline temp = wrapHnd->canInline(callerHnd, calleeHnd); API_LEAVE(canInline); return temp; } diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index cf87223f71760b..c19a7d2e50a716 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -4657,6 +4657,9 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl // Figure out what locals are address-taken. // DoPhase(this, PHASE_STR_ADRLCL, &Compiler::fgMarkAddressExposedLocals); + // Run a simple forward substitution pass. + // + DoPhase(this, PHASE_FWD_SUB, &Compiler::fgForwardSub); // Apply the type update to implicit byref parameters; also choose (based on address-exposed // analysis) which implicit byref promotions to keep (requires copy to initialize) or discard. diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 967d27eac4703b..69d88c4a57e280 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -5506,7 +5506,7 @@ class Compiler // Does value-numbering for a block assignment. void fgValueNumberBlockAssignment(GenTree* tree); - bool fgValueNumberIsStructReinterpretation(GenTreeLclVarCommon* lhsLclVarTree, GenTreeLclVarCommon* rhsLclVarTree); + bool fgValueNumberBlockAssignmentTypeCheck(LclVarDsc* dstVarDsc, FieldSeqNode* dstFldSeq, GenTree* src); // Does value-numbering for a cast tree. void fgValueNumberCastTree(GenTree* tree); @@ -6423,7 +6423,7 @@ class Compiler bool fgMorphCanUseLclFldForCopy(unsigned lclNum1, unsigned lclNum2); - GenTreeLclVar* fgMorphTryFoldObjAsLclVar(GenTreeObj* obj); + GenTreeLclVar* fgMorphTryFoldObjAsLclVar(GenTreeObj* obj, bool destroyNodes = true); GenTreeOp* fgMorphCommutative(GenTreeOp* tree); GenTree* fgMorphCastedBitwiseOp(GenTreeOp* tree); @@ -6562,6 +6562,10 @@ class Compiler void fgMarkAddressExposedLocals(); void fgMarkAddressExposedLocals(Statement* stmt); + PhaseStatus fgForwardSub(); + bool fgForwardSubBlock(BasicBlock* block); + bool fgForwardSubStatement(Statement* statement); + static fgWalkPreFn fgUpdateSideEffectsPre; static fgWalkPostFn fgUpdateSideEffectsPost; diff --git a/src/coreclr/jit/compphases.h b/src/coreclr/jit/compphases.h index 8f72dcce2360cd..3b1907e86fde0b 100644 --- a/src/coreclr/jit/compphases.h +++ b/src/coreclr/jit/compphases.h @@ -43,6 +43,7 @@ CompPhaseNameMacro(PHASE_UPDATE_FINALLY_FLAGS, "Update finally target flags", CompPhaseNameMacro(PHASE_COMPUTE_PREDS, "Compute preds", "PREDS", false, -1, false) CompPhaseNameMacro(PHASE_EARLY_UPDATE_FLOW_GRAPH,"Update flow graph early pass", "UPD-FG-E", false, -1, false) CompPhaseNameMacro(PHASE_STR_ADRLCL, "Morph - Structs/AddrExp", "MOR-STRAL",false, -1, false) +CompPhaseNameMacro(PHASE_FWD_SUB, "Forward Substitution", "FWD-SUB", false, -1, false) CompPhaseNameMacro(PHASE_MORPH_IMPBYREF, "Morph - ByRefs", "MOR-BYREF",false, -1, false) CompPhaseNameMacro(PHASE_PROMOTE_STRUCTS, "Morph - Promote Structs", "PROMOTER" ,false, -1, false) CompPhaseNameMacro(PHASE_MORPH_GLOBAL, "Morph - Global", "MOR-GLOB", false, -1, false) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index d90c5771ce1a96..c203a1729dd401 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -423,6 +423,10 @@ bool emitter::AreFlagsSetToZeroCmp(regNumber reg, emitAttr opSize, genTreeOps tr case IF_RWR: case IF_RRD: case IF_RRW: + case IF_RWR_RRD_RRD: + case IF_RWR_RRD_MRD: + case IF_RWR_RRD_ARD: + case IF_RWR_RRD_SRD: break; default: return false; diff --git a/src/coreclr/jit/forwardsub.cpp b/src/coreclr/jit/forwardsub.cpp new file mode 100644 index 00000000000000..77f0c6d99f4363 --- /dev/null +++ b/src/coreclr/jit/forwardsub.cpp @@ -0,0 +1,790 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "jitpch.h" + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------------ +// Simple Forward Substitution +// +// This phase tries to reconnect trees that were split early on by +// phases like the importer and inlining. We run it before morph +// to provide more context for morph's tree based optimizations, and +// we run it after the local address visitor because that phase sets +// address exposure for locals and computes (early) ref counts. +// +// The general pattern we look for is +// +// Statement(n): +// GT_ASG(lcl, tree) +// Statement(n+1): +// ... use of lcl ... +// +// where those are the only appearances of lcl and lcl is not address +// exposed. +// +// The "optimization" here transforms this to +// +// ~~Statement(n)~~ (removed) +// Statement(n+1): +// ... use of tree ... +// +// As always our main concerns are throughput, legality, profitability, +// and ensuring downstream phases do not get confused. +// +// For throughput, we try and early out on illegal or unprofitable cases +// before doing the more costly bits of analysis. We only scan a limited +// amount of IR and just give up if we can't find what we are looking for. +// +// If we're successful we will backtrack a bit, to try and catch cases like +// +// Statement(n): +// lcl1 = tree1 +// Statement(n+1): +// lcl2 = tree2 +// Statement(n+2): +// use ... lcl1 ... use ... lcl2 ... +// +// If we can forward sub tree2, then the def and use of lcl1 become +// adjacent. +// +// For legality we must show that evaluating "tree" at its new position +// can't change any observable behavior. This largely means running an +// interference analysis between tree and the portion of Statement(n+1) +// that will evaluate before "tree". This analysis is complicated by some +// missing flags on trees, in particular modelling the potential uses +// of exposed locals. We run supplementary scans looking for those. +// +// Ideally we'd update the tree with our findings, or better yet ensure +// that upstream phases didn't leave the wrong flags. +// +// For profitability we first try and avoid code growth. We do this +// by only substituting in cases where lcl has exactly one def and one use. +// This info is computed for us but the RCS_Early ref counting done during +// the immediately preceeding fgMarkAddressExposedLocals phase. +// +// Because of this, once we've substituted "tree" we know that lcl is dead +// and we can remove the assignment statement. +// +// Even with ref count screening, we don't know for sure where the +// single use of local might be, so we have to seach for it. +// +// We also take pains not to create overly large trees as the recursion +// done by morph incorporates a lot of state; deep trees may lead to +// stack overflows. +// +// There are a fair number of ad-hoc restrictions on what can be +// substituted where; these reflect various blemishes or implicit +// contracts in our IR shapes that we should either remove or mandate. +// +// Possible enhancements: +// * Allow fwd sub of "simple, cheap" trees when there's more than one use. +// * Search more widely for the use. +// * Use height/depth to avoid blowing morph's recursion, rather than tree size. +// * Sub across a block boundary if successor block is unique, join-free, +// and in the same EH region. +// * Rerun this later, after we have built SSA, and handle single-def single-use +// from SSA perspective. +// * Fix issue in morph that can unsoundly reorder call args, and remove +// extra effects computation from ForwardSubVisitor. +// * We can be more aggressive with GTF_IND_INVARIANT / GTF_IND_NONFAULTING +// nodes--even though they may be marked GTF_GLOB_REF, they can be freely +// reordered. See if this offers any benefit. +// +//------------------------------------------------------------------------ + +//------------------------------------------------------------------------ +// fgForwardSub: run forward substitution in this method +// +// Returns: +// suitable phase status +// +PhaseStatus Compiler::fgForwardSub() +{ + if (!opts.OptimizationEnabled()) + { + return PhaseStatus::MODIFIED_NOTHING; + } + +#if defined(DEBUG) + if (JitConfig.JitNoForwardSub() > 0) + { + return PhaseStatus::MODIFIED_NOTHING; + } +#endif + + bool changed = false; + + for (BasicBlock* const block : Blocks()) + { + JITDUMP("\n\n===> " FMT_BB "\n", block->bbNum); + changed |= fgForwardSubBlock(block); + } + + return changed ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING; +} + +//------------------------------------------------------------------------ +// fgForwardSubBlock: run forward substitution in this block +// +// Arguments: +// block -- block to process +// +// Returns: +// true if any IR was modified +// +bool Compiler::fgForwardSubBlock(BasicBlock* block) +{ + Statement* stmt = block->firstStmt(); + Statement* lastStmt = block->lastStmt(); + bool changed = false; + + while (stmt != lastStmt) + { + Statement* const prevStmt = stmt->GetPrevStmt(); + Statement* const nextStmt = stmt->GetNextStmt(); + bool const substituted = fgForwardSubStatement(stmt); + + if (substituted) + { + fgRemoveStmt(block, stmt); + changed = true; + } + + // Try backtracking if we substituted. + // + if (substituted && (prevStmt != lastStmt) && prevStmt->GetRootNode()->OperIs(GT_ASG)) + { + // Yep, bactrack. + // + stmt = prevStmt; + } + else + { + // Move on to the next. + // + stmt = nextStmt; + } + } + + return changed; +} + +//------------------------------------------------------------------------ +// ForwardSubVisitor: tree visitor to locate uses of a local in a tree +// +// Also computes the set of side effects that happen "before" the use, +// and counts the size of the tree. +// +// Effects accounting is complicated by missing flags and by the need +// to avoid introducing interfering call args. +// +class ForwardSubVisitor final : public GenTreeVisitor +{ +public: + enum + { + ComputeStack = true, + DoPostOrder = true, + UseExecutionOrder = true + }; + + ForwardSubVisitor(Compiler* compiler, unsigned lclNum) + : GenTreeVisitor(compiler) + , m_use(nullptr) + , m_node(nullptr) + , m_parentNode(nullptr) + , m_callAncestor(nullptr) + , m_lclNum(lclNum) + , m_useCount(0) + , m_useFlags(GTF_EMPTY) + , m_accumulatedFlags(GTF_EMPTY) + , m_treeSize(0) + { + } + + Compiler::fgWalkResult PostOrderVisit(GenTree** use, GenTree* user) + { + m_treeSize++; + GenTree* const node = *use; + + if (node->OperIs(GT_LCL_VAR)) + { + unsigned const lclNum = node->AsLclVarCommon()->GetLclNum(); + + if (lclNum == m_lclNum) + { + m_useCount++; + + // Screen out contextual "uses" + // + GenTree* const parent = m_ancestors.Top(1); + bool const isDef = parent->OperIs(GT_ASG) && (parent->gtGetOp1() == node); + bool const isAddr = parent->OperIs(GT_ADDR); + + bool isCallTarget = false; + + // Quirk: + // + // fgGetStubAddrArg cannot handle complex trees (it calls gtClone) + // + if (parent->IsCall()) + { + GenTreeCall* const parentCall = parent->AsCall(); + isCallTarget = (parentCall->gtCallType == CT_INDIRECT) && (parentCall->gtCallAddr == node); + } + + if (!isDef && !isAddr && !isCallTarget) + { + m_node = node; + m_use = use; + m_useFlags = m_accumulatedFlags; + m_parentNode = parent; + + // If this use contributes to a call arg we need to + // remember the call and handle it specially when we + // see it later in the postorder walk. + // + for (int i = 1; i < m_ancestors.Height(); i++) + { + if (m_ancestors.Top(i)->IsCall()) + { + m_callAncestor = m_ancestors.Top(i)->AsCall(); + break; + } + } + } + } + + // Uses of address-exposed locals are modelled as global refs. + // + LclVarDsc* const varDsc = m_compiler->lvaGetDesc(lclNum); + + if (varDsc->IsAddressExposed()) + { + m_accumulatedFlags |= GTF_GLOB_REF; + } + } + + // Is this the use's call ancestor? + // + if ((m_callAncestor != nullptr) && (node == m_callAncestor)) + { + // To be conservative and avoid issues with morph + // reordering call args, we merge in effects of all args + // to this call. + // + // Remove this if/when morph's arg sorting is fixed. + // + GenTreeFlags oldUseFlags = m_useFlags; + + if (m_callAncestor->gtCallThisArg != nullptr) + { + m_useFlags |= (m_callAncestor->gtCallThisArg->GetNode()->gtFlags & GTF_GLOB_EFFECT); + } + + for (GenTreeCall::Use& use : m_callAncestor->Args()) + { + m_useFlags |= (use.GetNode()->gtFlags & GTF_GLOB_EFFECT); + } + + if (oldUseFlags != m_useFlags) + { + JITDUMP(" [added other call arg use flags: 0x%x]", m_useFlags & ~oldUseFlags); + } + } + + m_accumulatedFlags |= (node->gtFlags & GTF_GLOB_EFFECT); + + return fgWalkResult::WALK_CONTINUE; + } + + unsigned GetUseCount() const + { + return m_useCount; + } + + GenTree* GetNode() const + { + return m_node; + } + + GenTree** GetUse() const + { + return m_use; + } + + GenTree* GetParentNode() const + { + return m_parentNode; + } + + GenTreeFlags GetFlags() const + { + return m_useFlags; + } + + bool IsCallArg() const + { + return m_parentNode->IsCall(); + } + + unsigned GetComplexity() const + { + return m_treeSize; + } + +private: + GenTree** m_use; + GenTree* m_node; + GenTree* m_parentNode; + GenTreeCall* m_callAncestor; + unsigned m_lclNum; + unsigned m_useCount; + GenTreeFlags m_useFlags; + GenTreeFlags m_accumulatedFlags; + unsigned m_treeSize; +}; + +//------------------------------------------------------------------------ +// EffectsVisitor: tree visitor to compute missing effects of a tree. +// +class EffectsVisitor final : public GenTreeVisitor +{ +public: + enum + { + DoPostOrder = true, + UseExecutionOrder = true + }; + + EffectsVisitor(Compiler* compiler) : GenTreeVisitor(compiler), m_flags(GTF_EMPTY) + { + } + + Compiler::fgWalkResult PostOrderVisit(GenTree** use, GenTree* user) + { + GenTree* const node = *use; + m_flags |= node->gtFlags & GTF_ALL_EFFECT; + + if (node->OperIs(GT_LCL_VAR)) + { + unsigned const lclNum = node->AsLclVarCommon()->GetLclNum(); + LclVarDsc* const varDsc = m_compiler->lvaGetDesc(lclNum); + + if (varDsc->IsAddressExposed()) + { + m_flags |= GTF_GLOB_REF; + } + } + + return fgWalkResult::WALK_CONTINUE; + } + + GenTreeFlags GetFlags() + { + return m_flags; + } + +private: + GenTreeFlags m_flags; +}; + +//------------------------------------------------------------------------ +// fgForwardSubStatement: forward substitute this statement's +// computation to the next statement, if legal and profitable +// +// arguments: +// stmt - statement in question +// +// Returns: +// true if statement computation was forwarded. +// caller is responsible for removing the now-dead statement. +// +bool Compiler::fgForwardSubStatement(Statement* stmt) +{ + // Is this tree a def of a single use, unaliased local? + // + GenTree* const rootNode = stmt->GetRootNode(); + + if (!rootNode->OperIs(GT_ASG)) + { + return false; + } + + GenTree* const lhsNode = rootNode->gtGetOp1(); + + if (!lhsNode->OperIs(GT_LCL_VAR)) + { + return false; + } + + JITDUMP(" [%06u]: ", dspTreeID(rootNode)) + + unsigned const lclNum = lhsNode->AsLclVarCommon()->GetLclNum(); + LclVarDsc* const varDsc = lvaGetDesc(lclNum); + + // Leave pinned locals alone. + // This is just a perf opt -- we shouldn't find any uses. + // + if (varDsc->lvPinned) + { + JITDUMP(" pinned local\n"); + return false; + } + + // Only fwd sub if we expect no code duplication + // We expect one def and one use. + // + if (varDsc->lvRefCnt(RCS_EARLY) != 2) + { + JITDUMP(" not asg (single-use lcl)\n"); + return false; + } + + // And local is unalised + // + if (varDsc->IsAddressExposed()) + { + JITDUMP(" not asg (unaliased single-use lcl)\n"); + return false; + } + + // Could handle this case --perhaps-- but we'd want to update ref counts. + // + if (lvaIsImplicitByRefLocal(lclNum)) + { + JITDUMP(" implicit by-ref local\n"); + return false; + } + + // Check the tree to substitute. + // + // We could just extract the value portion and forward sub that, + // but cleanup would be more complicated. + // + GenTree* const rhsNode = rootNode->gtGetOp2(); + GenTree* fwdSubNode = rhsNode; + + // Can't substitute a qmark (unless the use is RHS of an assign... could check for this) + // Can't substitute GT_CATCH_ARG. + // Can't substitute GT_LCLHEAP. + // + // Don't substitute a no return call (trips up morph in some cases). + // + if (fwdSubNode->OperIs(GT_QMARK, GT_CATCH_ARG, GT_LCLHEAP)) + { + JITDUMP(" tree to sub is qmark, catch arg, or lcl heap\n"); + return false; + } + + if (fwdSubNode->IsCall() && fwdSubNode->AsCall()->IsNoReturn()) + { + JITDUMP(" tree to sub is a 'no return' call\n"); + return false; + } + + // Bail if sub node has embedded assignment. + // + if ((fwdSubNode->gtFlags & GTF_ASG) != 0) + { + JITDUMP(" tree to sub has effects\n"); + return false; + } + + // Bail if sub node has mismatched types. + // Might be able to tolerate these by retyping. + // + if (lhsNode->TypeGet() != fwdSubNode->TypeGet()) + { + JITDUMP(" mismatched types (assignment)\n"); + return false; + } + + if (gtGetStructHandleIfPresent(fwdSubNode) != gtGetStructHandleIfPresent(lhsNode)) + { + JITDUMP(" would change struct handle (assignment)\n"); + return false; + } + + // If lhs is mulit-reg, rhs must be too. + // + if (lhsNode->IsMultiRegNode() && !fwdSubNode->IsMultiRegNode()) + { + JITDUMP(" would change multi-reg (assignment)\n"); + return false; + } + + // Don't fwd sub overly large trees. + // Size limit here is ad-hoc. Need to tune. + // + // Consider instead using the height of the fwdSubNode. + // + unsigned const nodeLimit = 16; + + if (gtComplexityExceeds(&fwdSubNode, nodeLimit)) + { + JITDUMP(" tree to sub has more than %u nodes\n", nodeLimit); + return false; + } + + // Local and tree to substitute seem suitable. + // See if the next statement contains the one and only use. + // + Statement* const nextStmt = stmt->GetNextStmt(); + + // We often see stale flags, eg call flags after inlining. + // Try and clean these up. + // + gtUpdateStmtSideEffects(nextStmt); + gtUpdateStmtSideEffects(stmt); + + // Scan for the (single) use. + // + ForwardSubVisitor fsv(this, lclNum); + fsv.WalkTree(nextStmt->GetRootNodePointer(), nullptr); + + // LclMorph (via RCS_Early) said there was just one use. + // It had better have gotten this right. + // + assert(fsv.GetUseCount() <= 1); + + if ((fsv.GetUseCount() == 0) || (fsv.GetNode() == nullptr)) + { + JITDUMP(" no next stmt use\n"); + return false; + } + + JITDUMP(" [%06u] is only use of [%06u] (V%02u) ", dspTreeID(fsv.GetNode()), dspTreeID(lhsNode), lclNum); + + // If next statement already has a large tree, hold off + // on making it even larger. + // + // We use total node count. Consider instead using the depth of the use and the + // height of the fwdSubNode. + // + unsigned const nextTreeLimit = 200; + if ((fsv.GetComplexity() > nextTreeLimit) && gtComplexityExceeds(&fwdSubNode, 1)) + { + JITDUMP(" next stmt tree is too large (%u)\n", fsv.GetComplexity()); + return false; + } + + // Next statement seems suitable. + // See if we can forward sub without changing semantics. + // + GenTree* const nextRootNode = nextStmt->GetRootNode(); + + // Bail if types disagree. + // Might be able to tolerate these by retyping. + // + if (fsv.GetNode()->TypeGet() != fwdSubNode->TypeGet()) + { + JITDUMP(" mismatched types (substitution)\n"); + return false; + } + + // We can forward sub if + // + // the value of the fwdSubNode can't change and its evaluation won't cause side effects, + // + // or, + // + // if the next tree can't change the value of fwdSubNode or be impacted by fwdSubNode effects + // + const bool fwdSubNodeInvariant = ((fwdSubNode->gtFlags & GTF_ALL_EFFECT) == 0); + const bool nextTreeIsPureUpToUse = ((fsv.GetFlags() & (GTF_EXCEPT | GTF_GLOB_REF | GTF_CALL)) == 0); + if (!fwdSubNodeInvariant && !nextTreeIsPureUpToUse) + { + // Fwd sub may impact global values and or reorder exceptions... + // + JITDUMP(" potentially interacting effects\n"); + return false; + } + + // If we're relying on purity of fwdSubNode for legality of forward sub, + // do some extra checks for global uses that might not be reflected in the flags. + // + // TODO: remove this once we can trust upstream phases and/or gtUpdateStmtSideEffects + // to set GTF_GLOB_REF properly. + // + if (fwdSubNodeInvariant && ((fsv.GetFlags() & (GTF_CALL | GTF_ASG)) != 0)) + { + EffectsVisitor ev(this); + ev.WalkTree(&fwdSubNode, nullptr); + + if ((ev.GetFlags() & GTF_GLOB_REF) != 0) + { + JITDUMP(" potentially interacting effects (AX locals)\n"); + return false; + } + } + + // Finally, profitability checks. + // + // These conditions can be checked earlier in the final version to save some throughput. + // Perhaps allowing for bypass with jit stress. + // + // If fwdSubNode is an address-exposed local, forwarding it may lose optimizations. + // (maybe similar for dner?) + // + if (fwdSubNode->OperIs(GT_LCL_VAR)) + { + unsigned const fwdLclNum = fwdSubNode->AsLclVarCommon()->GetLclNum(); + LclVarDsc* const fwdVarDsc = lvaGetDesc(fwdLclNum); + + if (fwdVarDsc->IsAddressExposed()) + { + JITDUMP(" V%02u is address exposed\n", fwdLclNum); + return false; + } + } + + // Optimization: + // + // If we are about to substitute GT_OBJ, see if we can simplify it first. + // Not doing so can lead to regressions... + // + // Hold off on doing this for call args for now (per issue #51569). + // + if (fwdSubNode->OperIs(GT_OBJ) && !fsv.IsCallArg()) + { + const bool destroyNodes = false; + GenTree* const optTree = fgMorphTryFoldObjAsLclVar(fwdSubNode->AsObj(), destroyNodes); + if (optTree != nullptr) + { + JITDUMP(" [folding OBJ(ADDR(LCL...))]"); + fwdSubNode = optTree; + } + } + + // Quirks: + // + // We may sometimes lose or change a type handle. Avoid substituting if so. + // + if (gtGetStructHandleIfPresent(fwdSubNode) != gtGetStructHandleIfPresent(fsv.GetNode())) + { + JITDUMP(" would change struct handle (substitution)\n"); + return false; + } + +#ifdef FEATURE_SIMD + // Don't forward sub a SIMD call under a HW intrinsic node. + // LowerCallStruct is not prepared for this. + // + if (fwdSubNode->IsCall() && varTypeIsSIMD(fwdSubNode->TypeGet()) && fsv.GetParentNode()->OperIs(GT_HWINTRINSIC)) + { + JITDUMP(" simd returning call; hw intrinsic\n"); + return false; + } +#endif // FEATURE_SIMD + + // There are implicit assumptions downstream on where/how multi-reg ops + // can appear. + // + // Eg if fwdSubNode is a multi-reg call, parent node must be GT_ASG and the + // local being defined must be specially marked up. + // + if (fwdSubNode->IsMultiRegCall()) + { + GenTree* const parentNode = fsv.GetParentNode(); + + if (!parentNode->OperIs(GT_ASG)) + { + JITDUMP(" multi-reg call, parent not asg\n"); + return false; + } + + GenTree* const parentNodeLHS = parentNode->gtGetOp1(); + + if (!parentNodeLHS->OperIs(GT_LCL_VAR)) + { + JITDUMP(" multi-reg call, parent not asg(lcl, ...)\n"); + return false; + } + +#if defined(TARGET_X86) || defined(TARGET_ARM) + if (fwdSubNode->TypeGet() == TYP_LONG) + { + JITDUMP(" TYP_LONG fwd sub node, target is x86/arm\n"); + return false; + } +#endif // defined(TARGET_X86) || defined(TARGET_ARM) + + GenTreeLclVar* const parentNodeLHSLocal = parentNodeLHS->AsLclVar(); + + unsigned const lhsLclNum = parentNodeLHSLocal->GetLclNum(); + LclVarDsc* const lhsVarDsc = lvaGetDesc(lhsLclNum); + + JITDUMP(" [marking V%02u as multi-reg-ret]", lhsLclNum); + lhsVarDsc->lvIsMultiRegRet = true; + parentNodeLHSLocal->SetMultiReg(); + } + + // If a method returns a multi-reg type, only forward sub locals, + // and ensure the local and operand have the required markup. + // + // (see eg impFixupStructReturnType) + // + if (compMethodReturnsMultiRegRetType() && fsv.GetParentNode()->OperIs(GT_RETURN)) + { + if (!fwdSubNode->OperIs(GT_LCL_VAR)) + { + JITDUMP(" parent is return, fwd sub node is not lcl var\n"); + return false; + } + +#if defined(TARGET_X86) || defined(TARGET_ARM) + if (fwdSubNode->TypeGet() == TYP_LONG) + { + JITDUMP(" TYP_LONG fwd sub node, target is x86/arm\n"); + return false; + } +#endif // defined(TARGET_X86) || defined(TARGET_ARM) + + GenTreeLclVar* const fwdSubNodeLocal = fwdSubNode->AsLclVar(); + + unsigned const fwdLclNum = fwdSubNodeLocal->GetLclNum(); + LclVarDsc* const fwdVarDsc = lvaGetDesc(fwdLclNum); + + JITDUMP(" [marking V%02u as multi-reg-ret]", fwdLclNum); + fwdVarDsc->lvIsMultiRegRet = true; + fwdSubNodeLocal->SetMultiReg(); + fwdSubNodeLocal->gtFlags |= GTF_DONT_CSE; + } + + // If the use is a multi-reg arg, don't forward sub non-locals. + // + if (fsv.GetNode()->IsMultiRegNode() && !fwdSubNode->IsMultiRegNode()) + { + JITDUMP(" would change multi-reg (substitution)\n"); + return false; + } + + // If the intial has truncate on store semantics, we need to replicate + // that here with a cast. + // + if (varDsc->lvNormalizeOnStore() && fgCastNeeded(fwdSubNode, varDsc->TypeGet())) + { + JITDUMP(" [adding cast for normalize on store]"); + fwdSubNode = gtNewCastNode(TYP_INT, fwdSubNode, false, varDsc->TypeGet()); + } + + // Looks good, forward sub! + // + GenTree** use = fsv.GetUse(); + *use = fwdSubNode; + + if (!fwdSubNodeInvariant) + { + gtUpdateStmtSideEffects(nextStmt); + } + + JITDUMP(" -- fwd subbing [%06u]; new next stmt is\n", dspTreeID(fwdSubNode)); + DISPSTMT(nextStmt); + + return true; +} diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 35b9d2d829ca42..1b99f5171cef08 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -2415,8 +2415,9 @@ unsigned Compiler::gtSetMultiOpOrder(GenTreeMultiOp* multiOp) costEx = IND_COST_EX; costSz = 2; - GenTree* addr = hwTree->Op(1)->gtEffectiveVal(); - level = gtSetEvalOrder(addr); + GenTree* const addrNode = hwTree->Op(1); + level = gtSetEvalOrder(addrNode); + GenTree* const addr = addrNode->gtEffectiveVal(); // See if we can form a complex addressing mode. if (addr->OperIs(GT_ADD) && gtMarkAddrMode(addr, &costEx, &costSz, hwTree->TypeGet())) @@ -5793,6 +5794,12 @@ GenTree* Compiler::gtNewStringLiteralNode(InfoAccessType iat, void* pValue) // GenTreeIntCon* Compiler::gtNewStringLiteralLength(GenTreeStrCon* node) { + if (node->IsStringEmptyField()) + { + JITDUMP("Folded String.Empty.Length to 0\n"); + return gtNewIconNode(0); + } + int length = -1; const char16_t* str = info.compCompHnd->getStringLiteral(node->gtScpHnd, node->gtSconCPX, &length); if (length >= 0) @@ -5802,11 +5809,11 @@ GenTreeIntCon* Compiler::gtNewStringLiteralLength(GenTreeStrCon* node) // str can be NULL for dynamic context if (str != nullptr) { - JITDUMP("String '\"%ws\".Length' is '%d'\n", str, length) + JITDUMP("Folded '\"%ws\".Length' to '%d'\n", str, length) } else { - JITDUMP("String 'CNS_STR.Length' is '%d'\n", length) + JITDUMP("Folded 'CNS_STR.Length' to '%d'\n", length) } return iconNode; } @@ -11685,11 +11692,34 @@ GenTree* Compiler::gtFoldExprCompare(GenTree* tree) return tree; } - /* Currently we can only fold when the two subtrees exactly match */ + // Currently we can only fold when the two subtrees exactly match + // and everything is side effect free. + // + if (((tree->gtFlags & GTF_SIDE_EFFECT) != 0) || !GenTree::Compare(op1, op2, true)) + { + // No folding. + // + return tree; + } - if ((tree->gtFlags & GTF_SIDE_EFFECT) || GenTree::Compare(op1, op2, true) == false) + // GTF_ORDER_SIDEEFF here may indicate volatile subtrees. + // Or it may indicate a non-null assertion prop into an indir subtree. + // + // Check the operands. + // + if ((tree->gtFlags & GTF_ORDER_SIDEEFF) != 0) { - return tree; /* return unfolded tree */ + // If op1 is "volatle" and op2 is not, we can still fold. + // + const bool op1MayBeVolatile = (op1->gtFlags & GTF_ORDER_SIDEEFF) != 0; + const bool op2MayBeVolatile = (op2->gtFlags & GTF_ORDER_SIDEEFF) != 0; + + if (!op1MayBeVolatile || op2MayBeVolatile) + { + // No folding. + // + return tree; + } } GenTree* cons; @@ -15917,6 +15947,9 @@ bool GenTree::IsFieldAddr(Compiler* comp, GenTree** pBaseAddr, FieldSeqNode** pF // will effectively treat such cases ("possible" in unsafe code) as undefined behavior. if (comp->eeIsFieldStatic(fldSeq->GetFieldHandle())) { + // TODO-VNTypes: this code is out of sync w.r.t. boxed statics that are numbered with + // VNF_PtrToStatic and treated as "simple" while here we treat them as "complex". + // TODO-VNTypes: we will always return the "baseAddr" here for now, but strictly speaking, // we only need to do that if we have a shared field, to encode the logical "instantiation" // argument. In all other cases, this serves no purpose and just leads to redundant maps. diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 085bc17a1e5107..b023c2bb8c52d4 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -3240,11 +3240,19 @@ struct GenTreeDblCon : public GenTree /* gtStrCon -- string constant (GT_CNS_STR) */ +#define EMPTY_STRING_SCON (unsigned)-1 + struct GenTreeStrCon : public GenTree { unsigned gtSconCPX; CORINFO_MODULE_HANDLE gtScpHnd; + // Returns true if this GT_CNS_STR was imported for String.Empty field + bool IsStringEmptyField() + { + return gtSconCPX == EMPTY_STRING_SCON && gtScpHnd == nullptr; + } + // Because this node can come from an inlined method we need to // have the scope handle, since it will become a helper call. GenTreeStrCon(unsigned sconCPX, CORINFO_MODULE_HANDLE mod DEBUGARG(bool largeNode = false)) @@ -6420,7 +6428,6 @@ struct Statement , m_lastILOffset(BAD_IL_OFFSET) , m_stmtID(stmtID) #endif - , m_compilerAdded(false) { } @@ -6507,16 +6514,6 @@ struct Statement m_prev = prevStmt; } - bool IsCompilerAdded() const - { - return m_compilerAdded; - } - - void SetCompilerAdded() - { - m_compilerAdded = true; - } - bool IsPhiDefnStmt() const { return m_rootNode->IsPhiDefn(); @@ -6553,8 +6550,6 @@ struct Statement IL_OFFSET m_lastILOffset; // The instr offset at the end of this statement. unsigned m_stmtID; #endif - - bool m_compilerAdded; // Was the statement created by optimizer? }; // StatementList: adapter class for forward iteration of the statement linked list using range-based `for`, diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b9cc2ff883d64a..ac361b08e8eb5f 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -8645,9 +8645,6 @@ var_types Compiler::impImportCall(OPCODE opcode, opcodeNames[opcode], callInfo->kind, varTypeName(callRetTyp), structSize); } #endif - // This should be checked in impImportBlockCode. - assert(!compIsForInlining() || !(impInlineInfo->inlineCandidateInfo->dwRestrictions & INLINE_RESPECT_BOUNDARY)); - sig = &calliSig; } else // (opcode != CEE_CALLI) @@ -8677,14 +8674,6 @@ var_types Compiler::impImportCall(OPCODE opcode, #endif if (compIsForInlining()) { - /* Does this call site have security boundary restrictions? */ - - if (impInlineInfo->inlineCandidateInfo->dwRestrictions & INLINE_RESPECT_BOUNDARY) - { - compInlineResult->NoteFatal(InlineObservation::CALLSITE_CROSS_BOUNDARY_SECURITY); - return TYP_UNDEF; - } - /* Does the inlinee use StackCrawlMark */ if (mflags & CORINFO_FLG_DONT_INLINE_CALLER) @@ -12216,20 +12205,9 @@ void Compiler::impImportBlockCode(BasicBlock* block) break; case CEE_LDSTR: - - if (compIsForInlining()) - { - if (impInlineInfo->inlineCandidateInfo->dwRestrictions & INLINE_NO_CALLEE_LDSTR) - { - compInlineResult->NoteFatal(InlineObservation::CALLSITE_HAS_LDSTR_RESTRICTION); - return; - } - } - val = getU4LittleEndian(codeAddr); JITDUMP(" %08X", val); impPushOnStack(gtNewSconNode(val, info.compScopeHnd), tiRetVal); - break; case CEE_LDARG: @@ -14460,16 +14438,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) eeGetCallInfo(&resolvedToken, nullptr /* constraint typeRef*/, combine(CORINFO_CALLINFO_SECURITYCHECKS, CORINFO_CALLINFO_ALLOWINSTPARAM), &callInfo); - if (compIsForInlining()) - { - if (impInlineInfo->inlineCandidateInfo->dwRestrictions & INLINE_RESPECT_BOUNDARY) - { - // Check to see if this call violates the boundary. - compInlineResult->NoteFatal(InlineObservation::CALLSITE_CROSS_BOUNDARY_SECURITY); - return; - } - } - mflags = callInfo.methodFlags; if ((mflags & (CORINFO_FLG_STATIC | CORINFO_FLG_ABSTRACT)) != 0) @@ -14659,16 +14627,6 @@ void Compiler::impImportBlockCode(BasicBlock* block) /* CALLI does not respond to CONSTRAINED */ prefixFlags &= ~PREFIX_CONSTRAINED; - if (compIsForInlining()) - { - // CALLI doesn't have a method handle, so assume the worst. - if (impInlineInfo->inlineCandidateInfo->dwRestrictions & INLINE_RESPECT_BOUNDARY) - { - compInlineResult->NoteFatal(InlineObservation::CALLSITE_CROSS_BOUNDARY_CALLI); - return; - } - } - FALLTHROUGH; case CEE_CALLVIRT: @@ -15115,9 +15073,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) { assert(aflags & CORINFO_ACCESS_GET); - LPVOID pValue; - InfoAccessType iat = info.compCompHnd->emptyStringLiteral(&pValue); - op1 = gtNewStringLiteralNode(iat, pValue); + // Import String.Empty as "" (GT_CNS_STR with a fake SconCPX = 0) + op1 = gtNewSconNode(EMPTY_STRING_SCON, nullptr); goto FIELD_DONE; } break; @@ -19063,7 +19020,6 @@ void Compiler::impCheckCanInline(GenTreeCall* call, bool success = eeRunWithErrorTrap( [](Param* pParam) { - uint32_t dwRestrictions = 0; CorInfoInitClassResult initClassResult; #ifdef DEBUG @@ -19119,8 +19075,7 @@ void Compiler::impCheckCanInline(GenTreeCall* call, /* VM Inline check also ensures that the method is verifiable if needed */ CorInfoInline vmResult; - vmResult = pParam->pThis->info.compCompHnd->canInline(pParam->pThis->info.compMethodHnd, pParam->fncHandle, - &dwRestrictions); + vmResult = pParam->pThis->info.compCompHnd->canInline(pParam->pThis->info.compMethodHnd, pParam->fncHandle); if (vmResult == INLINE_FAIL) { @@ -19138,21 +19093,6 @@ void Compiler::impCheckCanInline(GenTreeCall* call, goto _exit; } - // check for unsupported inlining restrictions - assert((dwRestrictions & ~(INLINE_RESPECT_BOUNDARY | INLINE_NO_CALLEE_LDSTR | INLINE_SAME_THIS)) == 0); - - if (dwRestrictions & INLINE_SAME_THIS) - { - GenTree* thisArg = pParam->call->AsCall()->gtCallThisArg->GetNode(); - assert(thisArg); - - if (!pParam->pThis->impIsThis(thisArg)) - { - pParam->result->NoteFatal(InlineObservation::CALLSITE_REQUIRES_SAME_THIS); - goto _exit; - } - } - /* Get the method properties */ CORINFO_CLASS_HANDLE clsHandle; @@ -19204,7 +19144,6 @@ void Compiler::impCheckCanInline(GenTreeCall* call, pInfo->clsHandle = clsHandle; pInfo->exactContextHnd = pParam->exactContextHnd; pInfo->retExpr = nullptr; - pInfo->dwRestrictions = dwRestrictions; pInfo->preexistingSpillTemp = BAD_VAR_NUM; pInfo->clsAttr = clsAttr; pInfo->methAttr = pParam->methAttr; diff --git a/src/coreclr/jit/inline.def b/src/coreclr/jit/inline.def index a519471a3caec2..a4f84552edd98d 100644 --- a/src/coreclr/jit/inline.def +++ b/src/coreclr/jit/inline.def @@ -132,14 +132,11 @@ INLINE_OBSERVATION(CANT_EMBED_VARARGS_COOKIE, bool, "can't embed varargs cooki INLINE_OBSERVATION(CANT_CLASS_INIT, bool, "can't class init", FATAL, CALLSITE) INLINE_OBSERVATION(COMPILATION_ERROR, bool, "compilation error", FATAL, CALLSITE) INLINE_OBSERVATION(COMPILATION_FAILURE, bool, "failed to compile", FATAL, CALLSITE) -INLINE_OBSERVATION(CROSS_BOUNDARY_CALLI, bool, "cross-boundary calli", FATAL, CALLSITE) -INLINE_OBSERVATION(CROSS_BOUNDARY_SECURITY, bool, "cross-boundary security check", FATAL, CALLSITE) INLINE_OBSERVATION(EXCEEDS_THRESHOLD, bool, "exceeds profit threshold", FATAL, CALLSITE) INLINE_OBSERVATION(EXPLICIT_TAIL_PREFIX, bool, "explicit tail prefix", FATAL, CALLSITE) INLINE_OBSERVATION(GENERIC_DICTIONARY_LOOKUP, bool, "runtime dictionary lookup", FATAL, CALLSITE) INLINE_OBSERVATION(HAS_CALL_VIA_LDVIRTFTN, bool, "call via ldvirtftn", FATAL, CALLSITE) INLINE_OBSERVATION(HAS_COMPLEX_HANDLE, bool, "complex handle access", FATAL, CALLSITE) -INLINE_OBSERVATION(HAS_LDSTR_RESTRICTION, bool, "has ldstr VM restriction", FATAL, CALLSITE) INLINE_OBSERVATION(IMPLICIT_REC_TAIL_CALL, bool, "implicit recursive tail call", FATAL, CALLSITE) INLINE_OBSERVATION(IS_CALL_TO_HELPER, bool, "target is helper", FATAL, CALLSITE) INLINE_OBSERVATION(IS_NOT_DIRECT, bool, "target not direct", FATAL, CALLSITE) @@ -162,7 +159,6 @@ INLINE_OBSERVATION(OVER_BUDGET, bool, "inline exceeds budget", INLINE_OBSERVATION(OVER_INLINE_LIMIT, bool, "limited by JitInlineLimit", FATAL, CALLSITE) INLINE_OBSERVATION(PIN_IN_TRY_REGION, bool, "within try region, pinned", FATAL, CALLSITE) INLINE_OBSERVATION(RANDOM_REJECT, bool, "random reject", FATAL, CALLSITE) -INLINE_OBSERVATION(REQUIRES_SAME_THIS, bool, "requires same this", FATAL, CALLSITE) INLINE_OBSERVATION(RETURN_TYPE_MISMATCH, bool, "return type mismatch", FATAL, CALLSITE) INLINE_OBSERVATION(STFLD_NEEDS_HELPER, bool, "stfld needs helper", FATAL, CALLSITE) INLINE_OBSERVATION(TOO_MANY_LOCALS, bool, "too many locals", FATAL, CALLSITE) diff --git a/src/coreclr/jit/inline.h b/src/coreclr/jit/inline.h index 9eacfb34a15138..7182bdf78fa92a 100644 --- a/src/coreclr/jit/inline.h +++ b/src/coreclr/jit/inline.h @@ -581,7 +581,6 @@ struct InlineCandidateInfo : public GuardedDevirtualizationCandidateInfo CORINFO_CLASS_HANDLE clsHandle; CORINFO_CONTEXT_HANDLE exactContextHnd; GenTree* retExpr; - DWORD dwRestrictions; unsigned preexistingSpillTemp; unsigned clsAttr; unsigned methAttr; diff --git a/src/coreclr/jit/instr.cpp b/src/coreclr/jit/instr.cpp index 1cbe07cb69b1c3..e0ecfeab9f0847 100644 --- a/src/coreclr/jit/instr.cpp +++ b/src/coreclr/jit/instr.cpp @@ -2159,8 +2159,10 @@ void CodeGen::instGen_Set_Reg_To_Zero(emitAttr size, regNumber reg, insFlags fla { #if defined(TARGET_XARCH) GetEmitter()->emitIns_R_R(INS_xor, size, reg, reg); -#elif defined(TARGET_ARMARCH) +#elif defined(TARGET_ARM) GetEmitter()->emitIns_R_I(INS_mov, size, reg, 0 ARM_ARG(flags)); +#elif defined(TARGET_ARM64) + GetEmitter()->emitIns_Mov(INS_mov, size, reg, REG_ZR, /* canSkip */ true); #else #error "Unknown TARGET" #endif diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index 08d4c4a8c8675d..abb2ac86ef99cb 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -592,7 +592,7 @@ INST3(LAST_AVXVNNI_INSTRUCTION, "LAST_AVXVNNI_INSTRUCTION", IUM_WR, BAD_CODE, BA // BMI1 INST3(FIRST_BMI_INSTRUCTION, "FIRST_BMI_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_FLAGS_None) -INST3(andn, "andn", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF2), INS_Flags_IsDstDstSrcAVXInstruction) // Logical AND NOT +INST3(andn, "andn", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF2), Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Resets_CF | INS_Flags_IsDstDstSrcAVXInstruction) // Logical AND NOT INST3(blsi, "blsi", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), INS_Flags_IsDstDstSrcAVXInstruction) // Extract Lowest Set Isolated Bit INST3(blsmsk, "blsmsk", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), INS_Flags_IsDstDstSrcAVXInstruction) // Get Mask Up to Lowest Set Bit INST3(blsr, "blsr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_IsDstDstSrcAVXInstruction) // Reset Lowest Set Bit diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 1346c2069da170..b53588a6937217 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -118,6 +118,7 @@ CONFIG_INTEGER(JitNoCSE2, W("JitNoCSE2"), 0) CONFIG_INTEGER(JitNoForceFallback, W("JitNoForceFallback"), 0) // Set to non-zero to prevent NOWAY assert testing. // Overrides COMPlus_JitForceFallback and JIT stress // flags. +CONFIG_INTEGER(JitNoForwardSub, W("JitNoForwardSub"), 0) // Disables forward sub CONFIG_INTEGER(JitNoHoist, W("JitNoHoist"), 0) CONFIG_INTEGER(JitNoInline, W("JitNoInline"), 0) // Disables inlining of all methods CONFIG_INTEGER(JitNoMemoryBarriers, W("JitNoMemoryBarriers"), 0) // If 1, don't generate memory barriers diff --git a/src/coreclr/jit/lclmorph.cpp b/src/coreclr/jit/lclmorph.cpp index 66684e38e1a3bb..999a904c3b338f 100644 --- a/src/coreclr/jit/lclmorph.cpp +++ b/src/coreclr/jit/lclmorph.cpp @@ -442,14 +442,15 @@ class LocalAddressVisitor final : public GenTreeVisitor #endif // DEBUG } - // Morph promoted struct fields and count implicit byref argument occurrences. + // Morph promoted struct fields and count local occurrences. + // // Also create and push the value produced by the visited node. This is done here // rather than in PostOrderVisit because it makes it easy to handle nodes with an // arbitrary number of operands - just pop values until the value corresponding // to the visited node is encountered. fgWalkResult PreOrderVisit(GenTree** use, GenTree* user) { - GenTree* node = *use; + GenTree* const node = *use; if (node->OperIs(GT_FIELD)) { @@ -462,19 +463,29 @@ class LocalAddressVisitor final : public GenTreeVisitor if (node->OperIsLocal()) { - unsigned lclNum = node->AsLclVarCommon()->GetLclNum(); + unsigned const lclNum = node->AsLclVarCommon()->GetLclNum(); + LclVarDsc* const varDsc = m_compiler->lvaGetDesc(lclNum); + + UpdateEarlyRefCount(lclNum); - LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); if (varDsc->lvIsStructField) { - // Promoted field, increase counter for the parent lclVar. + // Promoted field, increase count for the parent lclVar. + // assert(!m_compiler->lvaIsImplicitByRefLocal(lclNum)); unsigned parentLclNum = varDsc->lvParentLcl; - UpdateEarlyRefCountForImplicitByRef(parentLclNum); + UpdateEarlyRefCount(parentLclNum); } - else + + if (varDsc->lvPromoted) { - UpdateEarlyRefCountForImplicitByRef(lclNum); + // Promoted struct, increase count for each promoted field. + // + for (unsigned childLclNum = varDsc->lvFieldLclStart; + childLclNum < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++childLclNum) + { + UpdateEarlyRefCount(childLclNum); + } } } @@ -1162,7 +1173,7 @@ class LocalAddressVisitor final : public GenTreeVisitor } //------------------------------------------------------------------------ - // UpdateEarlyRefCountForImplicitByRef: updates the ref count for implicit byref params. + // UpdateEarlyRefCount: updates the ref count for locals // // Arguments: // lclNum - the local number to update the count for. @@ -1171,19 +1182,24 @@ class LocalAddressVisitor final : public GenTreeVisitor // fgMakeOutgoingStructArgCopy checks the ref counts for implicit byref params when it decides // if it's legal to elide certain copies of them; // fgRetypeImplicitByRefArgs checks the ref counts when it decides to undo promotions. + // fgForwardSub uses ref counts to decide when to forward sub. // - void UpdateEarlyRefCountForImplicitByRef(unsigned lclNum) + void UpdateEarlyRefCount(unsigned lclNum) { + LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); + + // Note we don't need accurate counts when the values are large. + // + if (varDsc->lvRefCnt(RCS_EARLY) < USHRT_MAX) + { + varDsc->incLvRefCnt(1, RCS_EARLY); + } + if (!m_compiler->lvaIsImplicitByRefLocal(lclNum)) { return; } - LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum); - JITDUMP("LocalAddressVisitor incrementing ref count from %d to %d for implicit by-ref V%02d\n", - varDsc->lvRefCnt(RCS_EARLY), varDsc->lvRefCnt(RCS_EARLY) + 1, lclNum); - varDsc->incLvRefCnt(1, RCS_EARLY); - // See if this struct is an argument to a call. This information is recorded // via the weighted early ref count for the local, and feeds the undo promotion // heuristic. diff --git a/src/coreclr/jit/lir.cpp b/src/coreclr/jit/lir.cpp index 81d03b93f7b347..2f5b762214ef17 100644 --- a/src/coreclr/jit/lir.cpp +++ b/src/coreclr/jit/lir.cpp @@ -1338,7 +1338,10 @@ class CheckLclVarSemanticsHelper CheckLclVarSemanticsHelper(Compiler* compiler, const LIR::Range* range, SmallHashTable& unusedDefs) - : compiler(compiler), range(range), unusedDefs(unusedDefs), unusedLclVarReads(compiler->getAllocator()) + : compiler(compiler) + , range(range) + , unusedDefs(unusedDefs) + , unusedLclVarReads(compiler->getAllocator(CMK_DebugOnly)) { } @@ -1358,13 +1361,45 @@ class CheckLclVarSemanticsHelper AliasSet::NodeInfo nodeInfo(compiler, node); if (nodeInfo.IsLclVarRead() && !unusedDefs.Contains(node)) { - int count = 0; - unusedLclVarReads.TryGetValue(nodeInfo.LclNum(), &count); - unusedLclVarReads.AddOrUpdate(nodeInfo.LclNum(), count + 1); + jitstd::list* reads; + if (!unusedLclVarReads.TryGetValue(nodeInfo.LclNum(), &reads)) + { + reads = new (compiler, CMK_DebugOnly) jitstd::list(compiler->getAllocator(CMK_DebugOnly)); + unusedLclVarReads.AddOrUpdate(nodeInfo.LclNum(), reads); + } + + reads->push_back(node); } - // If this node is a lclVar write, it must be to a lclVar that does not have an outstanding read. - assert(!nodeInfo.IsLclVarWrite() || !unusedLclVarReads.Contains(nodeInfo.LclNum())); + if (nodeInfo.IsLclVarWrite()) + { + // If this node is a lclVar write, it must be not alias a lclVar with an outstanding read + jitstd::list* reads; + if (unusedLclVarReads.TryGetValue(nodeInfo.LclNum(), &reads)) + { + for (GenTree* read : *reads) + { + AliasSet::NodeInfo readInfo(compiler, read); + assert(readInfo.IsLclVarRead() && readInfo.LclNum() == nodeInfo.LclNum()); + unsigned readStart = readInfo.LclOffs(); + unsigned readEnd = readStart + genTypeSize(read->TypeGet()); + unsigned writeStart = nodeInfo.LclOffs(); + unsigned writeEnd = writeStart + genTypeSize(node->TypeGet()); + if ((readEnd > writeStart) && (writeEnd > readStart)) + { + JITDUMP( + "Write to unaliased local overlaps outstanding read (write: %u..%u, read: %u..%u)\n", + writeStart, writeEnd, readStart, readEnd); + JITDUMP("Read:\n"); + DISPTREERANGE(const_cast(*range), read); + JITDUMP("Write:\n"); + DISPTREERANGE(const_cast(*range), node); + assert(!"Write to unaliased local overlaps outstanding read"); + break; + } + } + } + } } return true; @@ -1393,14 +1428,22 @@ class CheckLclVarSemanticsHelper AliasSet::NodeInfo operandInfo(compiler, operand); if (operandInfo.IsLclVarRead()) { - int count; - const bool removed = unusedLclVarReads.TryRemove(operandInfo.LclNum(), &count); - assert(removed); + jitstd::list* reads; + const bool foundList = unusedLclVarReads.TryGetValue(operandInfo.LclNum(), &reads); + assert(foundList); - if (count > 1) + bool found = false; + for (jitstd::list::iterator it = reads->begin(); it != reads->end(); ++it) { - unusedLclVarReads.AddOrUpdate(operandInfo.LclNum(), count - 1); + if (*it == operand) + { + reads->erase(it); + found = true; + break; + } } + + assert(found || !"Could not find consumed local in unusedLclVarReads"); } } } @@ -1408,8 +1451,8 @@ class CheckLclVarSemanticsHelper private: Compiler* compiler; const LIR::Range* range; - SmallHashTable& unusedDefs; - SmallHashTable unusedLclVarReads; + SmallHashTable& unusedDefs; + SmallHashTable*, 16U> unusedLclVarReads; }; //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index b111d73db6a995..2697a9892dca3b 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -139,7 +139,7 @@ GenTree* Lowering::LowerNode(GenTree* node) case GT_AND: case GT_OR: case GT_XOR: - return LowerBinaryArithmeticCommon(node->AsOp()); + return LowerBinaryArithmetic(node->AsOp()); case GT_MUL: case GT_MULHI: @@ -5133,53 +5133,6 @@ GenTree* Lowering::LowerAdd(GenTreeOp* node) return nullptr; } -//------------------------------------------------------------------------ -// LowerBinaryArithmeticCommon: lowers the given binary arithmetic node. -// -// Recognizes opportunities for using target-independent "combined" nodes -// (currently AND_NOT on ARMArch). Performs containment checks. -// -// Arguments: -// node - the arithmetic node to lower -// -// Returns: -// The next node to lower. -// -GenTree* Lowering::LowerBinaryArithmeticCommon(GenTreeOp* binOp) -{ - // TODO-CQ-XArch: support BMI2 "andn" in codegen and condition - // this logic on the support for the instruction set on XArch. - CLANG_FORMAT_COMMENT_ANCHOR; - -#ifdef TARGET_ARMARCH - if (comp->opts.OptimizationEnabled() && binOp->OperIs(GT_AND)) - { - GenTree* opNode = nullptr; - GenTree* notNode = nullptr; - if (binOp->gtGetOp1()->OperIs(GT_NOT)) - { - notNode = binOp->gtGetOp1(); - opNode = binOp->gtGetOp2(); - } - else if (binOp->gtGetOp2()->OperIs(GT_NOT)) - { - notNode = binOp->gtGetOp2(); - opNode = binOp->gtGetOp1(); - } - - if (notNode != nullptr) - { - binOp->gtOp1 = opNode; - binOp->gtOp2 = notNode->AsUnOp()->gtGetOp1(); - binOp->ChangeOper(GT_AND_NOT); - BlockRange().Remove(notNode); - } - } -#endif - - return LowerBinaryArithmetic(binOp); -} - //------------------------------------------------------------------------ // LowerUnsignedDivOrMod: Lowers a GT_UDIV/GT_UMOD node. // diff --git a/src/coreclr/jit/lower.h b/src/coreclr/jit/lower.h index 95843b6bded47e..b6a6c178f7e544 100644 --- a/src/coreclr/jit/lower.h +++ b/src/coreclr/jit/lower.h @@ -297,7 +297,6 @@ class Lowering final : public Phase void LowerStoreIndir(GenTreeStoreInd* node); GenTree* LowerAdd(GenTreeOp* node); GenTree* LowerMul(GenTreeOp* mul); - GenTree* LowerBinaryArithmeticCommon(GenTreeOp* binOp); GenTree* LowerBinaryArithmetic(GenTreeOp* binOp); bool LowerUnsignedDivOrMod(GenTreeOp* divMod); GenTree* LowerConstIntDivOrMod(GenTree* node); @@ -344,7 +343,8 @@ class Lowering final : public Phase void LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node); void LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node); void LowerHWIntrinsicWithElement(GenTreeHWIntrinsic* node); - GenTree* TryLowerAndOpToResetLowestSetBit(GenTreeOp* binOp); + GenTree* TryLowerAndOpToResetLowestSetBit(GenTreeOp* andNode); + GenTree* TryLowerAndOpToAndNot(GenTreeOp* andNode); #elif defined(TARGET_ARM64) bool IsValidConstForMovImm(GenTreeHWIntrinsic* node); void LowerHWIntrinsicFusedMultiplyAddScalar(GenTreeHWIntrinsic* node); diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 67e1269dfd429a..41b80fbee67233 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -292,6 +292,30 @@ GenTree* Lowering::LowerMul(GenTreeOp* mul) // GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp) { + if (comp->opts.OptimizationEnabled() && binOp->OperIs(GT_AND)) + { + GenTree* opNode = nullptr; + GenTree* notNode = nullptr; + if (binOp->gtGetOp1()->OperIs(GT_NOT)) + { + notNode = binOp->gtGetOp1(); + opNode = binOp->gtGetOp2(); + } + else if (binOp->gtGetOp2()->OperIs(GT_NOT)) + { + notNode = binOp->gtGetOp2(); + opNode = binOp->gtGetOp1(); + } + + if (notNode != nullptr) + { + binOp->gtOp1 = opNode; + binOp->gtOp2 = notNode->AsUnOp()->gtGetOp1(); + binOp->ChangeOper(GT_AND_NOT); + BlockRange().Remove(notNode); + } + } + ContainCheckBinary(binOp); return binOp->gtNext; diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 37459907558a0b..266d642014fd02 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -162,6 +162,9 @@ GenTree* Lowering::LowerMul(GenTreeOp* mul) //------------------------------------------------------------------------ // LowerBinaryArithmetic: lowers the given binary arithmetic node. // +// Recognizes opportunities for using target-independent "combined" nodes +// Performs containment checks. +// // Arguments: // node - the arithmetic node to lower // @@ -173,10 +176,16 @@ GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp) #ifdef FEATURE_HW_INTRINSICS if (comp->opts.OptimizationEnabled() && binOp->OperIs(GT_AND) && varTypeIsIntegral(binOp)) { - GenTree* blsrNode = TryLowerAndOpToResetLowestSetBit(binOp); - if (blsrNode != nullptr) + GenTree* replacementNode = TryLowerAndOpToAndNot(binOp); + if (replacementNode != nullptr) + { + return replacementNode->gtNext; + } + + replacementNode = TryLowerAndOpToResetLowestSetBit(binOp); + if (replacementNode != nullptr) { - return blsrNode->gtNext; + return replacementNode->gtNext; } } #endif @@ -3726,7 +3735,7 @@ void Lowering::LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node) } //---------------------------------------------------------------------------------------------- -// Lowering::TryLowerAndOpToResetLowestSetBit: Lowers a tree AND(X, ADD(X, -1) to HWIntrinsic::ResetLowestSetBit +// Lowering::TryLowerAndOpToResetLowestSetBit: Lowers a tree AND(X, ADD(X, -1)) to HWIntrinsic::ResetLowestSetBit // // Arguments: // andNode - GT_AND node of integral type @@ -3734,6 +3743,8 @@ void Lowering::LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node) // Return Value: // Returns the replacement node if one is created else nullptr indicating no replacement // +// Notes: +// Performs containment checks on the replacement node if one is created GenTree* Lowering::TryLowerAndOpToResetLowestSetBit(GenTreeOp* andNode) { assert(andNode->OperIs(GT_AND) && varTypeIsIntegral(andNode)); @@ -3802,6 +3813,86 @@ GenTree* Lowering::TryLowerAndOpToResetLowestSetBit(GenTreeOp* andNode) return blsrNode; } +//---------------------------------------------------------------------------------------------- +// Lowering::TryLowerAndOpToAndNot: Lowers a tree AND(X, NOT(Y)) to HWIntrinsic::AndNot +// +// Arguments: +// andNode - GT_AND node of integral type +// +// Return Value: +// Returns the replacement node if one is created else nullptr indicating no replacement +// +// Notes: +// Performs containment checks on the replacement node if one is created +GenTree* Lowering::TryLowerAndOpToAndNot(GenTreeOp* andNode) +{ + assert(andNode->OperIs(GT_AND) && varTypeIsIntegral(andNode)); + + GenTree* opNode = nullptr; + GenTree* notNode = nullptr; + if (andNode->gtGetOp1()->OperIs(GT_NOT)) + { + notNode = andNode->gtGetOp1(); + opNode = andNode->gtGetOp2(); + } + else if (andNode->gtGetOp2()->OperIs(GT_NOT)) + { + notNode = andNode->gtGetOp2(); + opNode = andNode->gtGetOp1(); + } + + if (opNode == nullptr) + { + return nullptr; + } + + // We want to avoid using "andn" when one of the operands is both a source and the destination and is also coming + // from memory. In this scenario, we will get smaller and likely faster code by using the RMW encoding of `and` + if (IsBinOpInRMWStoreInd(andNode)) + { + return nullptr; + } + + NamedIntrinsic intrinsic; + if (andNode->TypeIs(TYP_LONG) && comp->compOpportunisticallyDependsOn(InstructionSet_BMI1_X64)) + { + intrinsic = NamedIntrinsic::NI_BMI1_X64_AndNot; + } + else if (comp->compOpportunisticallyDependsOn(InstructionSet_BMI1)) + { + intrinsic = NamedIntrinsic::NI_BMI1_AndNot; + } + else + { + return nullptr; + } + + LIR::Use use; + if (!BlockRange().TryGetUse(andNode, &use)) + { + return nullptr; + } + + // note that parameter order for andn is ~y, x so these are purposefully reversed when creating the node + GenTreeHWIntrinsic* andnNode = + comp->gtNewScalarHWIntrinsicNode(andNode->TypeGet(), notNode->AsUnOp()->gtGetOp1(), opNode, intrinsic); + + JITDUMP("Lower: optimize AND(X, NOT(Y)))\n"); + DISPNODE(andNode); + JITDUMP("to:\n"); + DISPNODE(andnNode); + + use.ReplaceWith(andnNode); + + BlockRange().InsertBefore(andNode, andnNode); + BlockRange().Remove(andNode); + BlockRange().Remove(notNode); + + ContainCheckHWIntrinsic(andnNode); + + return andnNode; +} + #endif // FEATURE_HW_INTRINSICS //---------------------------------------------------------------------------------------------- diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index f07fe3ca9ed02b..b3e9e8fa82977f 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -5184,7 +5184,9 @@ GenTree* Compiler::fgMorphArrayIndex(GenTree* tree) noway_assert(elemTyp != TYP_STRUCT || elemStructType != nullptr); // Fold "cns_str"[cns_index] to ushort constant - if (opts.OptimizationEnabled() && asIndex->Arr()->OperIs(GT_CNS_STR) && asIndex->Index()->IsIntCnsFitsInI32()) + // NOTE: don't do it for empty string, the operation will fail anyway + if (opts.OptimizationEnabled() && asIndex->Arr()->OperIs(GT_CNS_STR) && + !asIndex->Arr()->AsStrCon()->IsStringEmptyField() && asIndex->Index()->IsIntCnsFitsInI32()) { const int cnsIndex = static_cast(asIndex->Index()->AsIntConCommon()->IconValue()); if (cnsIndex >= 0) @@ -6265,20 +6267,32 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) FieldSeqNode* fldSeq = !isBoxedStatic ? GetFieldSeqStore()->CreateSingleton(symHnd) : FieldSeqStore::NotAField(); -#ifdef TARGET_64BIT + // TODO-CQ: enable this optimization for 32 bit targets. bool isStaticReadOnlyInited = false; - bool plsSpeculative = true; - if (info.compCompHnd->getStaticFieldCurrentClass(symHnd, &plsSpeculative) != NO_CLASS_HANDLE) +#ifdef TARGET_64BIT + if (tree->TypeIs(TYP_REF) && !isBoxedStatic) { - isStaticReadOnlyInited = !plsSpeculative; + bool pIsSpeculative = true; + if (info.compCompHnd->getStaticFieldCurrentClass(symHnd, &pIsSpeculative) != NO_CLASS_HANDLE) + { + isStaticReadOnlyInited = !pIsSpeculative; + } } +#endif // TARGET_64BIT + + // TODO: choices made below have mostly historical reasons and + // should be unified to always use the IND(
) form. + CLANG_FORMAT_COMMENT_ANCHOR; - // even if RelocTypeHint is REL32 let's still prefer IND over GT_CLS_VAR - // for static readonly fields of statically initialized classes - thus we can - // apply GTF_IND_INVARIANT flag and make it hoistable/CSE-friendly - if (isStaticReadOnlyInited || (IMAGE_REL_BASED_REL32 != eeGetRelocTypeHint(fldAddr))) +#ifdef TARGET_64BIT + bool preferIndir = + isBoxedStatic || isStaticReadOnlyInited || (IMAGE_REL_BASED_REL32 != eeGetRelocTypeHint(fldAddr)); +#else // !TARGET_64BIT + bool preferIndir = isBoxedStatic; +#endif // !TARGET_64BIT + + if (preferIndir) { - // The address is not directly addressible, so force it into a constant, so we handle it properly. GenTreeFlags handleKind = GTF_EMPTY; if (isBoxedStatic) { @@ -6321,7 +6335,6 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) return fgMorphSmpOp(tree); } else -#endif // TARGET_64BIT { // Only volatile or classinit could be set, and they map over noway_assert((tree->gtFlags & ~(GTF_FLD_VOLATILE | GTF_FLD_INITCLASS | GTF_COMMON_MASK)) == 0); @@ -9422,11 +9435,18 @@ GenTree* Compiler::fgMorphConst(GenTree* tree) tree->gtFlags &= ~(GTF_ALL_EFFECT | GTF_REVERSE_OPS); - if (tree->OperGet() != GT_CNS_STR) + if (!tree->OperIs(GT_CNS_STR)) { return tree; } + if (tree->AsStrCon()->IsStringEmptyField()) + { + LPVOID pValue; + InfoAccessType iat = info.compCompHnd->emptyStringLiteral(&pValue); + return fgMorphTree(gtNewStringLiteralNode(iat, pValue)); + } + // TODO-CQ: Do this for compCurBB->isRunRarely(). Doing that currently will // guarantee slow performance for that block. Instead cache the return value // of CORINFO_HELP_STRCNS and go to cache first giving reasonable perf. @@ -9482,6 +9502,7 @@ GenTree* Compiler::fgMorphConst(GenTree* tree) // // Arguments: // obj - the obj node. +// destroyNodes -- destroy nodes that are optimized away // // Return value: // GenTreeLclVar if the obj can be replaced by it, null otherwise. @@ -9492,7 +9513,7 @@ GenTree* Compiler::fgMorphConst(GenTree* tree) // for some platforms does not expect struct `LCL_VAR` as a source, so // it needs more work. // -GenTreeLclVar* Compiler::fgMorphTryFoldObjAsLclVar(GenTreeObj* obj) +GenTreeLclVar* Compiler::fgMorphTryFoldObjAsLclVar(GenTreeObj* obj, bool destroyNodes) { if (opts.OptimizationEnabled()) { @@ -9525,8 +9546,12 @@ GenTreeLclVar* Compiler::fgMorphTryFoldObjAsLclVar(GenTreeObj* obj) lclVar->gtFlags &= ~GTF_DONT_CSE; lclVar->gtFlags |= (obj->gtFlags & GTF_DONT_CSE); - DEBUG_DESTROY_NODE(obj); - DEBUG_DESTROY_NODE(addr); + if (destroyNodes) + { + DEBUG_DESTROY_NODE(obj); + DEBUG_DESTROY_NODE(addr); + } + return lclVar; } } @@ -11535,6 +11560,24 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) case GT_PUTARG_TYPE: return fgMorphTree(tree->AsUnOp()->gtGetOp1()); + case GT_NULLCHECK: + { + op1 = tree->AsUnOp()->gtGetOp1(); + if (op1->IsCall()) + { + GenTreeCall* const call = op1->AsCall(); + if (call->IsHelperCall() && s_helperCallProperties.NonNullReturn(eeGetHelperNum(call->gtCallMethHnd))) + { + JITDUMP("\nNULLCHECK on [%06u] will always succeed\n", dspTreeID(call)); + + // TODO: Can we also remove the call? + // + return fgMorphTree(call); + } + } + } + break; + default: break; } diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index dd2f3a8246ede1..64b0675c045e1d 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -1159,7 +1159,7 @@ bool Compiler::optExtractInitTestIncr( noway_assert(initStmt != nullptr && (initStmt->GetNextStmt() == nullptr)); // If it is a duplicated loop condition, skip it. - if (initStmt->IsCompilerAdded()) + if (initStmt->GetRootNode()->OperIs(GT_JTRUE)) { bool doGetPrev = true; #ifdef DEBUG @@ -3771,10 +3771,9 @@ PhaseStatus Compiler::optUnrollLoops() Statement* incrStmt = testStmt->GetPrevStmt(); noway_assert(incrStmt != nullptr); - if (initStmt->IsCompilerAdded()) + if (initStmt->GetRootNode()->OperIs(GT_JTRUE)) { // Must be a duplicated loop condition. - noway_assert(initStmt->GetRootNode()->gtOper == GT_JTRUE); dupCond = true; initStmt = initStmt->GetPrevStmt(); @@ -4601,8 +4600,6 @@ bool Compiler::optInvertWhileLoop(BasicBlock* block) { clonedStmt->SetDebugInfo(stmt->GetDebugInfo()); } - - clonedStmt->SetCompilerAdded(); } assert(foundCondTree); @@ -5835,12 +5832,9 @@ void Compiler::optPerformHoistExpr(GenTree* origExpr, BasicBlock* exprBb, unsign preHead->bbFlags |= (exprBb->bbFlags & (BBF_HAS_IDX_LEN | BBF_HAS_NULLCHECK)); Statement* hoistStmt = gtNewStmt(hoist); - hoistStmt->SetCompilerAdded(); - - /* simply append the statement at the end of the preHead's list */ + // Simply append the statement at the end of the preHead's list. Statement* firstStmt = preHead->firstStmt(); - if (firstStmt != nullptr) { /* append after last statement */ diff --git a/src/coreclr/jit/phase.cpp b/src/coreclr/jit/phase.cpp index 5f2e2172c6f4a5..8d002dfe08c614 100644 --- a/src/coreclr/jit/phase.cpp +++ b/src/coreclr/jit/phase.cpp @@ -180,6 +180,7 @@ void Phase::PostPhase(PhaseStatus status) PHASE_MERGE_FINALLY_CHAINS, PHASE_CLONE_FINALLY, PHASE_MERGE_THROWS, + PHASE_FWD_SUB, PHASE_MORPH_GLOBAL, PHASE_INVERT_LOOPS, PHASE_OPTIMIZE_LAYOUT, diff --git a/src/coreclr/jit/sideeffects.cpp b/src/coreclr/jit/sideeffects.cpp index b7c896d14098fd..fe6a8a7d6064c5 100644 --- a/src/coreclr/jit/sideeffects.cpp +++ b/src/coreclr/jit/sideeffects.cpp @@ -136,7 +136,7 @@ AliasSet::AliasSet() // node - The node in question. // AliasSet::NodeInfo::NodeInfo(Compiler* compiler, GenTree* node) - : m_compiler(compiler), m_node(node), m_flags(0), m_lclNum(0) + : m_compiler(compiler), m_node(node), m_flags(0), m_lclNum(0), m_lclOffs(0) { if (node->IsCall()) { @@ -174,6 +174,7 @@ AliasSet::NodeInfo::NodeInfo(Compiler* compiler, GenTree* node) bool isMemoryAccess = false; bool isLclVarAccess = false; unsigned lclNum = 0; + unsigned lclOffs = 0; if (node->OperIsIndir()) { // If the indirection targets a lclVar, we can be more precise with regards to aliasing by treating the @@ -183,6 +184,7 @@ AliasSet::NodeInfo::NodeInfo(Compiler* compiler, GenTree* node) { isLclVarAccess = true; lclNum = address->AsLclVarCommon()->GetLclNum(); + lclOffs = address->AsLclVarCommon()->GetLclOffs(); } else { @@ -197,6 +199,7 @@ AliasSet::NodeInfo::NodeInfo(Compiler* compiler, GenTree* node) { isLclVarAccess = true; lclNum = node->AsLclVarCommon()->GetLclNum(); + lclOffs = node->AsLclVarCommon()->GetLclOffs(); } else { @@ -221,7 +224,8 @@ AliasSet::NodeInfo::NodeInfo(Compiler* compiler, GenTree* node) if (isLclVarAccess) { m_flags |= ALIAS_READS_LCL_VAR; - m_lclNum = lclNum; + m_lclNum = lclNum; + m_lclOffs = lclOffs; } } else @@ -234,7 +238,8 @@ AliasSet::NodeInfo::NodeInfo(Compiler* compiler, GenTree* node) if (isLclVarAccess) { m_flags |= ALIAS_WRITES_LCL_VAR; - m_lclNum = lclNum; + m_lclNum = lclNum; + m_lclOffs = lclOffs; } } } diff --git a/src/coreclr/jit/sideeffects.h b/src/coreclr/jit/sideeffects.h index 8e2fe1cd788b4b..e7ffdb0a7311b8 100644 --- a/src/coreclr/jit/sideeffects.h +++ b/src/coreclr/jit/sideeffects.h @@ -72,6 +72,7 @@ class AliasSet final GenTree* m_node; unsigned m_flags; unsigned m_lclNum; + unsigned m_lclOffs; public: NodeInfo(Compiler* compiler, GenTree* node); @@ -112,6 +113,12 @@ class AliasSet final return m_lclNum; } + inline unsigned LclOffs() const + { + assert(IsLclVarRead() || IsLclVarWrite()); + return m_lclOffs; + } + inline bool WritesAnyLocation() const { return (m_flags & (ALIAS_WRITES_ADDRESSABLE_LOCATION | ALIAS_WRITES_LCL_VAR)) != 0; diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 947f774fbdac05..4be6e1a93a4cdb 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -7802,8 +7802,24 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree) GenTree* baseAddr = nullptr; FieldSeqNode* fldSeq = nullptr; + if (argIsVNFunc && funcApp.m_func == VNF_PtrToStatic) + { + FieldSeqNode* fldSeq = vnStore->FieldSeqVNToFieldSeq(funcApp.m_args[1]); + assert(fldSeq != nullptr); // We should never see an empty sequence here. + + if (fldSeq != FieldSeqStore::NotAField()) + { + ValueNum newHeapVN = vnStore->VNApplySelectorsAssign(VNK_Liberal, fgCurMemoryVN[GcHeap], fldSeq, + rhsVNPair.GetLiberal(), lhs->TypeGet()); + recordGcHeapStore(tree, newHeapVN DEBUGARG("static field store")); + } + else + { + fgMutateGcHeap(tree DEBUGARG("indirect store at NotAField PtrToStatic address")); + } + } // Is the LHS an array index expression? - if (argIsVNFunc && funcApp.m_func == VNF_PtrToArrElem) + else if (argIsVNFunc && funcApp.m_func == VNF_PtrToArrElem) { CORINFO_CLASS_HANDLE elemTypeEq = CORINFO_CLASS_HANDLE(vnStore->ConstantValue(funcApp.m_args[0])); @@ -8002,370 +8018,223 @@ void Compiler::fgValueNumberBlockAssignment(GenTree* tree) GenTree* lhs = tree->gtGetOp1(); GenTree* rhs = tree->gtGetOp2(); - if (tree->OperIsInitBlkOp()) + GenTreeLclVarCommon* lclVarTree; + bool isEntire; + if (tree->DefinesLocal(this, &lclVarTree, &isEntire)) { - GenTreeLclVarCommon* lclVarTree; - bool isEntire; + assert(lclVarTree->gtFlags & GTF_VAR_DEF); + // Should not have been recorded as updating the GC heap. + assert(!GetMemorySsaMap(GcHeap)->Lookup(tree)); - if (tree->DefinesLocal(this, &lclVarTree, &isEntire)) - { - assert(lclVarTree->gtFlags & GTF_VAR_DEF); - // Should not have been recorded as updating the GC heap. - assert(!GetMemorySsaMap(GcHeap)->Lookup(tree)); + unsigned lhsLclNum = lclVarTree->GetLclNum(); + unsigned lclDefSsaNum = GetSsaNumForLocalVarDef(lclVarTree); - unsigned lclDefSsaNum = GetSsaNumForLocalVarDef(lclVarTree); + // Ignore vars that we excluded from SSA (for example, because they're address-exposed). They don't have + // SSA names in which to store VN's on defs. We'll yield unique VN's when we read from them. + if (lclDefSsaNum != SsaConfig::RESERVED_SSA_NUM) + { + FieldSeqNode* lhsFldSeq = nullptr; + LclVarDsc* lhsVarDsc = lvaGetDesc(lhsLclNum); - // Ignore vars that we excluded from SSA (for example, because they're address-exposed). They don't have - // SSA names in which to store VN's on defs. We'll yield unique VN's when we read from them. - if (lclDefSsaNum != SsaConfig::RESERVED_SSA_NUM) + if (lhs->IsLocalExpr(this, &lclVarTree, &lhsFldSeq)) { - LclVarDsc* lclVarDsc = lvaGetDesc(lclVarTree); + noway_assert(lclVarTree->GetLclNum() == lhsLclNum); + } + else + { + GenTree* lhsAddr = lhs->AsIndir()->Addr(); - // Should not have been recorded as updating ByrefExposed. - assert(!GetMemorySsaMap(ByrefExposed)->Lookup(tree)); + // For addr-of-local expressions, lib/cons shouldn't matter. + assert(lhsAddr->gtVNPair.BothEqual()); + ValueNum lhsAddrVN = lhsAddr->GetVN(VNK_Liberal); + + // Unpack the PtrToLoc value number of the address. + assert(vnStore->IsVNFunc(lhsAddrVN)); + + VNFuncApp lhsAddrFuncApp; + vnStore->GetVNFunc(lhsAddrVN, &lhsAddrFuncApp); + + assert(lhsAddrFuncApp.m_func == VNF_PtrToLoc); + assert(vnStore->IsVNConstant(lhsAddrFuncApp.m_args[0]) && + vnStore->ConstantValue(lhsAddrFuncApp.m_args[0]) == lhsLclNum); + lhsFldSeq = vnStore->FieldSeqVNToFieldSeq(lhsAddrFuncApp.m_args[1]); + } + + bool isNewUniq = false; + ValueNumPair newLhsLclVNPair = ValueNumPair(); + if (tree->OperIsInitBlkOp()) + { ValueNum lclVarVN = ValueNumStore::NoVN; if (isEntire && rhs->IsIntegralConst(0)) { // Note that it is possible to see pretty much any kind of type for the local // (not just TYP_STRUCT) here because of the ASG(BLK(ADDR(LCL_VAR/FLD)), 0) form. - lclVarVN = (lclVarDsc->TypeGet() == TYP_STRUCT) ? vnStore->VNForZeroObj(lclVarDsc->GetStructHnd()) - : vnStore->VNZeroForType(lclVarDsc->TypeGet()); + lclVarVN = (lhsVarDsc->TypeGet() == TYP_STRUCT) ? vnStore->VNForZeroObj(lhsVarDsc->GetStructHnd()) + : vnStore->VNZeroForType(lhsVarDsc->TypeGet()); } else { // Non-zero block init is very rare so we'll use a simple, unique VN here. - lclVarVN = vnStore->VNForExpr(compCurBB, lclVarDsc->TypeGet()); + lclVarVN = vnStore->VNForExpr(compCurBB, lhsVarDsc->TypeGet()); + isNewUniq = true; } - lclVarDsc->GetPerSsaData(lclDefSsaNum)->m_vnPair.SetBoth(lclVarVN); -#ifdef DEBUG - if (verbose) - { - printf("Tree "); - Compiler::printTreeID(tree); - printf(" assigned VN to local var V%02u/%d: ", lclVarTree->GetLclNum(), lclDefSsaNum); - vnPrint(lclVarVN, 1); - printf("\n"); - } -#endif // DEBUG - } - else if (lvaVarAddrExposed(lclVarTree->GetLclNum())) - { - fgMutateAddressExposedLocal(tree DEBUGARG("INITBLK - address-exposed local")); + newLhsLclVNPair.SetBoth(lclVarVN); } - } - else - { - // For now, arbitrary side effect on GcHeap/ByrefExposed. - // TODO-CQ: Why not be complete, and get this case right? - fgMutateGcHeap(tree DEBUGARG("INITBLK - non local")); - } - // Initblock's are of type void. Give them the void "value" -- they may occur in argument lists, which we - // want to be able to give VN's to. - tree->gtVNPair.SetBoth(ValueNumStore::VNForVoid()); - } - else - { - assert(tree->OperIsCopyBlkOp()); - // TODO-Cleanup: We should factor things so that we uniformly rely on "PtrTo" VN's, and - // the memory cases can be shared with assignments. - GenTreeLclVarCommon* lclVarTree = nullptr; - bool isEntire = false; - // Note that we don't care about exceptions here, since we're only using the values - // to perform an assignment (which happens after any exceptions are raised...) - - if (tree->DefinesLocal(this, &lclVarTree, &isEntire)) - { - // Should not have been recorded as updating the GC heap. - assert(!GetMemorySsaMap(GcHeap)->Lookup(tree)); - - unsigned lhsLclNum = lclVarTree->GetLclNum(); - FieldSeqNode* lhsFldSeq = nullptr; - unsigned lclDefSsaNum = GetSsaNumForLocalVarDef(lclVarTree); - LclVarDsc* lhsVarDsc = lvaGetDesc(lhsLclNum); - // If it's excluded from SSA, don't need to do anything. - if (lvaInSsa(lhsLclNum) && lclDefSsaNum != SsaConfig::RESERVED_SSA_NUM) + else { - // Should not have been recorded as updating ByrefExposed. - assert(!GetMemorySsaMap(ByrefExposed)->Lookup(tree)); - - if (lhs->IsLocalExpr(this, &lclVarTree, &lhsFldSeq)) - { - noway_assert(lclVarTree->GetLclNum() == lhsLclNum); - } - else - { - GenTree* lhsAddr; - if (lhs->OperIsBlk()) - { - lhsAddr = lhs->AsBlk()->Addr(); - } - else - { - assert(lhs->OperGet() == GT_IND); - lhsAddr = lhs->AsOp()->gtOp1; - } - - // For addr-of-local expressions, lib/cons shouldn't matter. - assert(lhsAddr->gtVNPair.BothEqual()); - ValueNum lhsAddrVN = lhsAddr->GetVN(VNK_Liberal); - - // Unpack the PtrToLoc value number of the address. - assert(vnStore->IsVNFunc(lhsAddrVN)); - - VNFuncApp lhsAddrFuncApp; - vnStore->GetVNFunc(lhsAddrVN, &lhsAddrFuncApp); - - assert(lhsAddrFuncApp.m_func == VNF_PtrToLoc); - assert(vnStore->IsVNConstant(lhsAddrFuncApp.m_args[0]) && - vnStore->ConstantValue(lhsAddrFuncApp.m_args[0]) == lhsLclNum); - - lhsFldSeq = vnStore->FieldSeqVNToFieldSeq(lhsAddrFuncApp.m_args[1]); - } + assert(tree->OperIsCopyBlkOp()); - // Now we need to get the proper RHS. - GenTreeLclVarCommon* rhsLclVarTree = nullptr; - LclVarDsc* rhsVarDsc = nullptr; - FieldSeqNode* rhsFldSeq = nullptr; - ValueNumPair rhsVNPair; - bool isNewUniq = false; - if (!rhs->OperIsIndir()) + if (fgValueNumberBlockAssignmentTypeCheck(lhsVarDsc, lhsFldSeq, rhs)) { - if (rhs->IsLocalExpr(this, &rhsLclVarTree, &rhsFldSeq)) - { - unsigned rhsLclNum = rhsLclVarTree->GetLclNum(); - rhsVarDsc = lvaGetDesc(rhsLclNum); - if (!lvaInSsa(rhsLclNum) || !rhsLclVarTree->HasSsaName() || - rhsFldSeq == FieldSeqStore::NotAField()) - { - rhsVNPair.SetBoth(vnStore->VNForExpr(compCurBB, rhsLclVarTree->TypeGet())); - isNewUniq = true; - } - else - { - rhsVNPair = rhsVarDsc->GetPerSsaData(rhsLclVarTree->GetSsaNum())->m_vnPair; - var_types indType = rhsLclVarTree->TypeGet(); - - rhsVNPair = vnStore->VNPairApplySelectors(rhsVNPair, rhsFldSeq, indType); - } - } - else - { - isNewUniq = true; - } + ValueNumPair rhsVNPair = vnStore->VNPNormalPair(rhs->gtVNPair); + ValueNumPair oldLhsLclVNPair = lhsVarDsc->GetPerSsaData(lclVarTree->GetSsaNum())->m_vnPair; + newLhsLclVNPair = + vnStore->VNPairApplySelectorsAssign(oldLhsLclVNPair, lhsFldSeq, rhsVNPair, lhs->TypeGet()); } else { - GenTree* srcAddr = rhs->AsIndir()->Addr(); - VNFuncApp srcAddrFuncApp; - if (srcAddr->IsLocalAddrExpr(this, &rhsLclVarTree, &rhsFldSeq)) - { - unsigned rhsLclNum = rhsLclVarTree->GetLclNum(); - rhsVarDsc = lvaGetDesc(rhsLclNum); - if (!lvaInSsa(rhsLclNum) || !rhsLclVarTree->HasSsaName() || - rhsFldSeq == FieldSeqStore::NotAField()) - { - isNewUniq = true; - } - else - { - rhsVNPair = rhsVarDsc->GetPerSsaData(rhsLclVarTree->GetSsaNum())->m_vnPair; - var_types indType = rhsLclVarTree->TypeGet(); - - rhsVNPair = vnStore->VNPairApplySelectors(rhsVNPair, rhsFldSeq, indType); - } - } - else if (vnStore->GetVNFunc(vnStore->VNLiberalNormalValue(srcAddr->gtVNPair), &srcAddrFuncApp)) - { - if (srcAddrFuncApp.m_func == VNF_PtrToStatic) - { - var_types indType = lclVarTree->TypeGet(); - ValueNum fieldSeqVN = srcAddrFuncApp.m_args[1]; - FieldSeqNode* fldSeqForStaticVar = vnStore->FieldSeqVNToFieldSeq(fieldSeqVN); -#ifdef DEBUG - FieldSeqNode* zeroOffsetFldSeq = nullptr; - if (GetZeroOffsetFieldMap()->Lookup(srcAddr, &zeroOffsetFldSeq)) - { - // Check that the zero offset field seq was attached for `srcAddr`. - assert(fldSeqForStaticVar->GetTail() == zeroOffsetFldSeq); - } -#endif - if (fldSeqForStaticVar != FieldSeqStore::NotAField()) - { - assert(fldSeqForStaticVar != nullptr); - - // We model statics as indices into GcHeap (which is a subset of ByrefExposed). - ValueNum selectedStaticVar; - size_t structSize = 0; - selectedStaticVar = vnStore->VNApplySelectors(VNK_Liberal, fgCurMemoryVN[GcHeap], - fldSeqForStaticVar, &structSize); - selectedStaticVar = - vnStore->VNApplySelectorsTypeCheck(selectedStaticVar, indType, structSize); - - rhsVNPair.SetLiberal(selectedStaticVar); - rhsVNPair.SetConservative(vnStore->VNForExpr(compCurBB, indType)); - } - else - { - JITDUMP(" *** Missing field sequence info for Src/RHS of COPYBLK\n"); - isNewUniq = true; - } - } - else if (srcAddrFuncApp.m_func == VNF_PtrToArrElem) - { - ValueNum elemLib = - fgValueNumberArrIndexVal(nullptr, &srcAddrFuncApp, vnStore->VNPForEmptyExcSet()); - rhsVNPair.SetLiberal(elemLib); - rhsVNPair.SetConservative(vnStore->VNForExpr(compCurBB, lclVarTree->TypeGet())); - } - else - { - isNewUniq = true; - } - } - else - { - isNewUniq = true; - } - } - - if (lhsFldSeq == FieldSeqStore::NotAField()) - { - // We don't have proper field sequence information for the lhs - // - JITDUMP(" *** Missing field sequence info for Dst/LHS of COPYBLK\n"); + newLhsLclVNPair.SetBoth(vnStore->VNForExpr(compCurBB, lhsVarDsc->TypeGet())); isNewUniq = true; } + } - if (!isNewUniq && (lclVarTree != nullptr) && (rhsLclVarTree != nullptr)) - { - isNewUniq = fgValueNumberIsStructReinterpretation(lclVarTree, rhsLclVarTree); - } + lhsVarDsc->GetPerSsaData(lclDefSsaNum)->m_vnPair = newLhsLclVNPair; +#ifdef DEBUG + if (verbose) + { + printf("Tree "); + Compiler::printTreeID(tree); + printf(" assigned VN to local var V%02u/%d: ", lhsLclNum, lclDefSsaNum); if (isNewUniq) { - rhsVNPair.SetBoth(vnStore->VNForExpr(compCurBB, lclVarTree->TypeGet())); - } - else // We will assign rhsVNPair into a map[lhsFldSeq] - { - if (lhsFldSeq != nullptr && isEntire) - { - // This can occur for structs with one field, itself of a struct type. - // We are assigning the one field and it is also the entire enclosing struct. - // - // Use an unique value number for the old map, as this is an an entire assignment - // and we won't have any other values in the map - ValueNumPair uniqueMap; - uniqueMap.SetBoth(vnStore->VNForExpr(compCurBB, lclVarTree->TypeGet())); - rhsVNPair = - vnStore->VNPairApplySelectorsAssign(uniqueMap, lhsFldSeq, rhsVNPair, lclVarTree->TypeGet()); - } - else - { - ValueNumPair oldLhsVNPair = lhsVarDsc->GetPerSsaData(lclVarTree->GetSsaNum())->m_vnPair; - rhsVNPair = vnStore->VNPairApplySelectorsAssign(oldLhsVNPair, lhsFldSeq, rhsVNPair, - lclVarTree->TypeGet()); - } + printf("new uniq "); } - - lhsVarDsc->GetPerSsaData(lclDefSsaNum)->m_vnPair = vnStore->VNPNormalPair(rhsVNPair); - -#ifdef DEBUG - if (verbose) - { - printf("Tree "); - Compiler::printTreeID(tree); - printf(" assigned VN to local var V%02u/%d: ", lhsLclNum, lclDefSsaNum); - if (isNewUniq) - { - printf("new uniq "); - } - vnpPrint(rhsVNPair, 1); - printf("\n"); - } -#endif // DEBUG - } - else if (lvaVarAddrExposed(lhsLclNum)) - { - fgMutateAddressExposedLocal(tree DEBUGARG("COPYBLK - address-exposed local")); - } - else - { - JITDUMP("LHS V%02u not in ssa at [%06u], so no VN assigned\n", lhsLclNum, dspTreeID(lclVarTree)); + vnpPrint(newLhsLclVNPair, 1); + printf("\n"); } +#endif // DEBUG + } + else if (lvaVarAddrExposed(lhsLclNum)) + { + fgMutateAddressExposedLocal(tree DEBUGARG("INITBLK/COPYBLK - address-exposed local")); } else { - // For now, arbitrary side effect on GcHeap/ByrefExposed. - // TODO-CQ: Why not be complete, and get this case right? - fgMutateGcHeap(tree DEBUGARG("COPYBLK - non local")); + JITDUMP("LHS V%02u not in ssa at [%06u], so no VN assigned\n", lhsLclNum, dspTreeID(lclVarTree)); } - // Copyblock's are of type void. Give them the void "value" -- they may occur in argument lists, which we want - // to be able to give VN's to. - tree->gtVNPair.SetBoth(ValueNumStore::VNForVoid()); } + else + { + // For now, arbitrary side effect on GcHeap/ByrefExposed. + // TODO-CQ: Why not be complete, and get this case right? + fgMutateGcHeap(tree DEBUGARG("INITBLK/COPYBLK - non local")); + } + + // Assignments produce no values so we give them the "Void" VN. + tree->gtVNPair = vnStore->VNPForVoid(); } //------------------------------------------------------------------------ -// fgValueNumberIsStructReinterpretation: Checks if there is a struct reinterpretation that prevent VN propagation. +// fgValueNumberBlockAssignmentTypeCheck: Checks if there is a struct reinterpretation that prevent VN propagation. // // Arguments: -// lhsLclVarTree - a lcl var tree on the lhs of the asg; -// rhsLclVarTree - a lcl var tree on the rhs of the asg; +// dstVarDsc - the descriptor for the local being assigned to +// dstFldSeq - the sequence of fields used for the assignment +// src - the source of the assignment, i. e. the RHS // // Return Value: -// True if the locals have different struct types and VN can't use rhs VN for lhs VN. -// False if locals have the same struct type or if this ASG is not a struct ASG. +// Whether "src"'s exact type matches that of the destination location. +// +// Notes: +// Currently this method only handles local destinations, it should be expanded to support more +// locations (static/instance fields, array elements) once/if "fgValueNumberBlockAssignment" +// supports them. // -bool Compiler::fgValueNumberIsStructReinterpretation(GenTreeLclVarCommon* lhsLclVarTree, - GenTreeLclVarCommon* rhsLclVarTree) +bool Compiler::fgValueNumberBlockAssignmentTypeCheck(LclVarDsc* dstVarDsc, FieldSeqNode* dstFldSeq, GenTree* src) { - assert(lhsLclVarTree != nullptr); - assert(rhsLclVarTree != nullptr); + if (dstFldSeq == FieldSeqStore::NotAField()) + { + // We don't have proper field sequence information for the lhs - assume arbitrary aliasing. + JITDUMP(" *** Missing field sequence info for Dst/LHS of COPYBLK\n"); + return false; + } - if (rhsLclVarTree->TypeGet() == TYP_STRUCT) + // With unsafe code or nested structs, we can end up with IR that has + // mismatched struct types on the LHS and RHS. We need to maintain the + // invariant that a node's VN corresponds exactly to its type. Failure + // to do so is a correctness problem. For example: + // + // S1 s1 = { ... }; // s1 = map + // S1.F0 = 0; // s1 = map[F0 := 0] + // S2 s2 = s1; // s2 = map[F0 := 0] (absent below checks) + // s2.F1 = 1; // s2 = map[F0 := 0][F1 := 1] + // s1 = s2; // s1 = map[F0 := 0][F1 := 1] + // + // int r = s1.F0; // map[F0 := 0][F1 := 1][F0] => map[F0 := 0][F0] => 0 + // + // If F1 and F0 physically alias (exist at the same offset, say), the above + // represents an incorrect optimization. + + var_types dstLocationType = TYP_UNDEF; + CORINFO_CLASS_HANDLE dstLocationStructHnd = NO_CLASS_HANDLE; + if (dstFldSeq == nullptr) { - if (rhsLclVarTree->TypeGet() == lhsLclVarTree->TypeGet()) + dstLocationType = dstVarDsc->TypeGet(); + if (dstLocationType == TYP_STRUCT) { - if (lhsLclVarTree->isLclField() || rhsLclVarTree->isLclField()) - { - // Jit does not have a real support for `LCL_FLD struct [FldSeq]` because it can't determinate their - // size - // when the fieldSeq is `NotAField`, but by mistake we could have - // `BLK(ADDR byref(LCL_FLD struct Fseq[]))` nowadays in out IR. - // Generate a unique VN for now, it currently won't match the other side, - // otherwise we would not have 'OBJ struct2 (ADDR(LCL_FLD struct1))` cast. - return true; - } + dstLocationStructHnd = dstVarDsc->GetStructHnd(); + } + } + else + { + // Have to normalize as "eeGetFieldType" will return TYP_STRUCT for TYP_SIMD. + dstLocationType = eeGetFieldType(dstFldSeq->GetTail()->GetFieldHandle(), &dstLocationStructHnd); + if (dstLocationType == TYP_STRUCT) + { + dstLocationType = impNormStructType(dstLocationStructHnd); + } + } - assert(lhsLclVarTree->OperIs(GT_LCL_VAR)); - assert(rhsLclVarTree->OperIs(GT_LCL_VAR)); + // This method is meant to handle TYP_STRUCT mismatches, bail early for anything else. + if (dstLocationType != src->TypeGet()) + { + JITDUMP(" *** Different types for Dst/Src of COPYBLK: %s != %s\n", varTypeName(dstLocationType), + varTypeName(src->TypeGet())); + return false; + } - const LclVarDsc* lhsVarDsc = lvaGetDesc(lhsLclVarTree); - const LclVarDsc* rhsVarDsc = lvaGetDesc(rhsLclVarTree); - assert(rhsVarDsc->TypeGet() == TYP_STRUCT); - assert(lhsVarDsc->TypeGet() == TYP_STRUCT); + // They're equal, and they're primitives. Allow, for now. TYP_SIMD is tentatively + // allowed here as well as, currently, there are no two vector types with public + // fields both that could reasonably alias each other. + if (dstLocationType != TYP_STRUCT) + { + return true; + } - CORINFO_CLASS_HANDLE rhsStructHnd = rhsVarDsc->GetStructHnd(); - CORINFO_CLASS_HANDLE lhsStructHnd = lhsVarDsc->GetStructHnd(); + // Figure out what the source's type really is. Note that this will miss + // struct fields of struct locals currently ("src" for them is an IND(struct)). + // Note as well that we're relying on the invariant that "node type == node's + // VN type" here (it would be expensive to recover the handle from "src"'s VN). + CORINFO_CLASS_HANDLE srcValueStructHnd = gtGetStructHandleIfPresent(src); + if (srcValueStructHnd == NO_CLASS_HANDLE) + { + JITDUMP(" *** Missing struct handle for Src of COPYBLK\n"); + return false; + } - if (rhsStructHnd != lhsStructHnd) - { - // This can occur for nested structs or for unsafe casts, when we have IR like - // struct1 = struct2. - // Use an unique value number for the old map, as we don't have information about - // the dst field values using dst FIELD_HANDLE. - // Note that other asignments, like struct1 = IND struct(ADDR(LCL_VAR long)) - // will be handled in `VNPairApplySelectorsAssign`, here we care only about - // `LCL_VAR structX = (*)LCL_VAR structY` cases. - JITDUMP(" *** Different struct handles for Dst/Src of COPYBLK\n"); - return true; - } - } + assert((dstLocationStructHnd != NO_CLASS_HANDLE) && (srcValueStructHnd != NO_CLASS_HANDLE)); + + if (dstLocationStructHnd != srcValueStructHnd) + { + JITDUMP(" *** Different struct handles for Dst/Src of COPYBLK: %s != %s\n", + eeGetClassName(dstLocationStructHnd), eeGetClassName(srcValueStructHnd)); + return false; } - return false; + return true; } void Compiler::fgValueNumberTree(GenTree* tree) @@ -8625,39 +8494,19 @@ void Compiler::fgValueNumberTree(GenTree* tree) ValueNumPair clsVarVNPair; GenTreeClsVar* clsVar = tree->AsClsVar(); FieldSeqNode* fldSeq = clsVar->gtFieldSeq; - assert(fldSeq != nullptr); // We need to have one. - CORINFO_FIELD_HANDLE fieldHnd = clsVar->gtClsVarHnd; - assert(fieldHnd != NO_FIELD_HANDLE); - ValueNum selectedStaticVar = ValueNumStore::NoVN; + assert((fldSeq != nullptr) && (fldSeq != FieldSeqStore::NotAField())); // We need to have one. - if (fldSeq == FieldSeqStore::NotAField()) - { - // This is the box for a "boxed static" - see "fgMorphField". - assert(gtIsStaticFieldPtrToBoxedStruct(clsVar->TypeGet(), fieldHnd)); - - // We will create an empty field sequence for VNF_PtrToStatic here. We will assume - // the actual sequence will get appended later, when processing the TARGET_POINTER_SIZE - // offset that is always added to this box to get to its payload. - - ValueNum fieldHndVN = vnStore->VNForHandle(ssize_t(fieldHnd), GTF_ICON_FIELD_HDL); - ValueNum fieldSeqVN = vnStore->VNForFieldSeq(nullptr); - clsVarVNPair.SetBoth(vnStore->VNForFunc(TYP_REF, VNF_PtrToStatic, fieldHndVN, fieldSeqVN)); - } - else - { - // This is a reference to heap memory. - // We model statics as indices into GcHeap (which is a subset of ByrefExposed). + // This is a reference to heap memory. + // We model statics as indices into GcHeap (which is a subset of ByrefExposed). + size_t structSize = 0; + ValueNum selectedStaticVar = + vnStore->VNApplySelectors(VNK_Liberal, fgCurMemoryVN[GcHeap], fldSeq, &structSize); + selectedStaticVar = + vnStore->VNApplySelectorsTypeCheck(selectedStaticVar, tree->TypeGet(), structSize); - size_t structSize = 0; - selectedStaticVar = - vnStore->VNApplySelectors(VNK_Liberal, fgCurMemoryVN[GcHeap], fldSeq, &structSize); - selectedStaticVar = - vnStore->VNApplySelectorsTypeCheck(selectedStaticVar, tree->TypeGet(), structSize); - - clsVarVNPair.SetLiberal(selectedStaticVar); - // The conservative interpretation always gets a new, unique VN. - clsVarVNPair.SetConservative(vnStore->VNForExpr(compCurBB, tree->TypeGet())); - } + clsVarVNPair.SetLiberal(selectedStaticVar); + // The conservative interpretation always gets a new, unique VN. + clsVarVNPair.SetConservative(vnStore->VNForExpr(compCurBB, tree->TypeGet())); // The ValueNum returned must represent the full-sized IL-Stack value // If we need to widen this value then we need to introduce a VNF_Cast here to represent @@ -8834,9 +8683,22 @@ void Compiler::fgValueNumberTree(GenTree* tree) if (!wasNewobj) { + // Indirections off of addresses for boxed statics represent bases for + // the address of the static itself. Here we will use "nullptr" for the + // field sequence and assume the actual static field will be appended to + // it later, as part of numbering the method table pointer offset addition. + if (addr->IsCnsIntOrI() && addr->IsIconHandle(GTF_ICON_STATIC_BOX_PTR)) + { + assert(addrNvnp.BothEqual() && (addrXvnp == vnStore->VNPForEmptyExcSet())); + ValueNum boxAddrVN = addrNvnp.GetLiberal(); + ValueNum fieldSeqVN = vnStore->VNForFieldSeq(nullptr); + ValueNum staticAddrVN = + vnStore->VNForFunc(tree->TypeGet(), VNF_PtrToStatic, boxAddrVN, fieldSeqVN); + tree->gtVNPair = ValueNumPair(staticAddrVN, staticAddrVN); + } // Is this invariant indirect expected to always return a non-null value? // TODO-VNTypes: non-null indirects should only be used for TYP_REFs. - if ((tree->gtFlags & GTF_IND_NONNULL) != 0) + else if ((tree->gtFlags & GTF_IND_NONNULL) != 0) { assert(tree->gtFlags & GTF_IND_NONFAULTING); tree->gtVNPair = vnStore->VNPairForFunc(tree->TypeGet(), VNF_NonNullIndirect, addrNvnp); @@ -10614,8 +10476,19 @@ void Compiler::fgValueNumberAddExceptionSetForIndirection(GenTree* tree, GenTree // The normal VN for base address is used to create the NullPtrExc ValueNumPair vnpBaseNorm = vnStore->VNPNormalPair(baseVNP); + ValueNumPair excChkSet = vnStore->VNPForEmptyExcSet(); + + if (!vnStore->IsKnownNonNull(vnpBaseNorm.GetLiberal())) + { + excChkSet.SetLiberal( + vnStore->VNExcSetSingleton(vnStore->VNForFunc(TYP_REF, VNF_NullPtrExc, vnpBaseNorm.GetLiberal()))); + } - ValueNumPair excChkSet = vnStore->VNPExcSetSingleton(vnStore->VNPairForFunc(TYP_REF, VNF_NullPtrExc, vnpBaseNorm)); + if (!vnStore->IsKnownNonNull(vnpBaseNorm.GetConservative())) + { + excChkSet.SetConservative( + vnStore->VNExcSetSingleton(vnStore->VNForFunc(TYP_REF, VNF_NullPtrExc, vnpBaseNorm.GetConservative()))); + } // Add the NullPtrExc to "tree"'s value numbers. tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, excChkSet); diff --git a/src/coreclr/jit/valuenumfuncs.h b/src/coreclr/jit/valuenumfuncs.h index fc10c05398cf03..f82c2ff603d07e 100644 --- a/src/coreclr/jit/valuenumfuncs.h +++ b/src/coreclr/jit/valuenumfuncs.h @@ -16,7 +16,7 @@ ValueNumFuncDef(NotAField, 0, false, false, false) // Value number function for ValueNumFuncDef(PtrToLoc, 2, false, true, false) // Pointer (byref) to a local variable. Args: VN's of: 0: var num, 1: FieldSeq. ValueNumFuncDef(PtrToArrElem, 4, false, false, false) // Pointer (byref) to an array element. Args: 0: array elem type eq class var_types value, VN's of: 1: array, 2: index, 3: FieldSeq. ValueNumFuncDef(PtrToStatic, 2, false, true, false) // Pointer (byref) to a static variable (or possibly a field thereof, if the static variable is a struct). - // Args: 0: (VN of) the field handle, 1: the field sequence, of which the first element is the static itself. + // Args: 0: (VN of) the box's address if the static is "boxed", 1: the field sequence, of which the first element is the static itself. ValueNumFuncDef(Phi, 2, false, false, false) // A phi function. Only occurs as arg of PhiDef or PhiMemoryDef. Arguments are SSA numbers of var being defined. ValueNumFuncDef(PhiDef, 3, false, false, false) // Args: 0: local var # (or -1 for memory), 1: SSA #, 2: VN of definition. diff --git a/src/coreclr/jit/valuenumtype.h b/src/coreclr/jit/valuenumtype.h index 1c991e5c05a971..5ed44e280f8f7e 100644 --- a/src/coreclr/jit/valuenumtype.h +++ b/src/coreclr/jit/valuenumtype.h @@ -96,6 +96,16 @@ struct ValueNumPair m_conservative = vn; } + bool operator==(const ValueNumPair& other) const + { + return (m_liberal == other.m_liberal) && (m_conservative == other.m_conservative); + } + + bool operator!=(const ValueNumPair& other) const + { + return !(*this == other); + } + void operator=(const ValueNumPair& vn2) { m_liberal = vn2.m_liberal; diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.props b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.props index b49f24ea2bc38d..4e8bbecff72873 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.props +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.props @@ -90,7 +90,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + diff --git a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs b/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs index 9909556b183305..f684094f9084db 100644 --- a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs +++ b/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs @@ -40,7 +40,7 @@ internal class LowLevelList { private const int _defaultCapacity = 4; - protected T?[] _items; + protected T[] _items; protected int _size; protected int _version; @@ -447,7 +447,7 @@ public void RemoveAt(int index) { Array.Copy(_items, index + 1, _items, index, _size - index); } - _items[_size] = default(T); + _items[_size] = default!; _version++; } @@ -549,7 +549,7 @@ public T Current } } - object System.Collections.IEnumerator.Current + object? System.Collections.IEnumerator.Current { get { diff --git a/src/coreclr/nativeaot/Directory.Build.props b/src/coreclr/nativeaot/Directory.Build.props index dddbec1ec7bfbd..9b732840b30907 100644 --- a/src/coreclr/nativeaot/Directory.Build.props +++ b/src/coreclr/nativeaot/Directory.Build.props @@ -31,7 +31,7 @@ $(NoWarn),0419,0649,CA2249,CA1830 - $(NoWarn);CS8600;CS8601;CS8602;CS8603;CS8604;CS8610;CS8618;CS8620;CS8625;CS8632;CS8765 + $(NoWarn);CS8600;CS8602;CS8603;CS8604;CS8610;CS8618;CS8620;CS8625;CS8632;CS8765 $(NoWarn);CA1810;CA1823;CA1825;CA2208;SA1129;SA1205;SA1400;SA1517 diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs index 7e738b4f2d32c5..f6af798344b761 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs @@ -1054,7 +1054,7 @@ public static unsafe bool AreTypesAssignableInternal(MethodTable* pSourceType, M return true; Key key = new Key(pSourceType, pTargetType, variation); - Entry entry = LookupInCache(s_cache, ref key); + Entry? entry = LookupInCache(s_cache, ref key); if (entry == null) return CacheMiss(ref key, pVisited); @@ -1072,7 +1072,7 @@ public static unsafe bool AreTypesAssignableInternal_SourceNotTarget_BoxedSource { Debug.Assert(pSourceType != pTargetType, "target is source"); Key key = new Key(pSourceType, pTargetType, AssignmentVariation.BoxedSource); - Entry entry = LookupInCache(s_cache, ref key); + Entry? entry = LookupInCache(s_cache, ref key); if (entry == null) return CacheMiss(ref key, pVisited); @@ -1113,7 +1113,7 @@ private static unsafe bool CacheMiss(ref Key key, EETypePairList* pVisited) Entry[] previousCache = Unsafe.As(s_previousCache.Target); if (previousCache != null) { - Entry previousEntry = LookupInCache(previousCache, ref key); + Entry? previousEntry = LookupInCache(previousCache, ref key); if (previousEntry != null) { result = previousEntry.Result; @@ -1140,7 +1140,7 @@ private static unsafe bool CacheMiss(ref Key key, EETypePairList* pVisited) try { // Avoid duplicate entries - Entry existingEntry = LookupInCache(s_cache, ref key); + Entry? existingEntry = LookupInCache(s_cache, ref key); if (existingEntry != null) return existingEntry.Result; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs index 7379e9ed471581..0059de15e5d9de 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs @@ -2,14 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.Reflection; +using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Loader; using System.Text; using System.Threading; +using Internal.Runtime; using Internal.Runtime.Augments; namespace Internal.Runtime.CompilerHelpers @@ -337,7 +340,7 @@ internal static unsafe void FixupModuleCell(ModuleFixupCell* pCell) if (hModule == IntPtr.Zero) { // Built-in rules didn't resolve the library. Use AssemblyLoadContext as a last chance attempt. - AssemblyLoadContext loadContext = AssemblyLoadContext.GetLoadContext(callingAssembly); + AssemblyLoadContext? loadContext = AssemblyLoadContext.GetLoadContext(callingAssembly); hModule = loadContext.GetResolvedUnmanagedDll(callingAssembly, moduleName); } @@ -591,6 +594,32 @@ internal static unsafe void CleanupVariant(IntPtr pDstNativeVariant) #endif } + public static unsafe object InitializeCustomMarshaller(RuntimeTypeHandle pParameterType, RuntimeTypeHandle pMarshallerType, string cookie, delegate* getInstanceMethod) + { + if (getInstanceMethod == null) + { + throw new ApplicationException(); + } + + if (!RuntimeImports.AreTypesAssignable(pMarshallerType.ToEETypePtr(), EETypePtr.EETypePtrOf())) + { + throw new ApplicationException(); + } + + var marshaller = CustomMarshallerTable.s_customMarshallersTable.GetOrAdd(new CustomMarshallerKey(pParameterType, pMarshallerType, cookie, getInstanceMethod)); + if (marshaller == null) + { + throw new ApplicationException(); + } + + if (!RuntimeImports.AreTypesAssignable(marshaller.EETypePtr, EETypePtr.EETypePtrOf())) + { + throw new ApplicationException(); + } + + return marshaller; + } + [StructLayout(LayoutKind.Sequential)] internal unsafe struct ModuleFixupCell { @@ -608,5 +637,52 @@ internal unsafe struct MethodFixupCell public ModuleFixupCell* Module; public CharSet CharSetMangling; } + + internal unsafe struct CustomMarshallerKey : IEquatable + { + public CustomMarshallerKey(RuntimeTypeHandle pParameterType, RuntimeTypeHandle pMarshallerType, string cookie, delegate* getInstanceMethod) + { + ParameterType = pParameterType; + MarshallerType = pMarshallerType; + Cookie = cookie; + GetInstanceMethod = getInstanceMethod; + } + + public RuntimeTypeHandle ParameterType { get; } + public RuntimeTypeHandle MarshallerType { get; } + public string Cookie { get; } + public delegate* GetInstanceMethod { get; } + + public override bool Equals(object obj) + { + if (!(obj is CustomMarshallerKey other)) + return false; + return Equals(other); + } + + public bool Equals(CustomMarshallerKey other) + { + return ParameterType.Equals(other.ParameterType) + && MarshallerType.Equals(other.MarshallerType) + && Cookie.Equals(other.Cookie); + } + + public override int GetHashCode() + { + return ParameterType.GetHashCode() + ^ MarshallerType.GetHashCode() + ^ Cookie.GetHashCode(); + } + } + + internal sealed class CustomMarshallerTable : ConcurrentUnifier + { + internal static CustomMarshallerTable s_customMarshallersTable = new CustomMarshallerTable(); + + protected unsafe override object Factory(CustomMarshallerKey key) + { + return key.GetInstanceMethod(key.Cookie); + } + } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 2284e13f661357..57ba9e2a3ab29c 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -445,7 +445,7 @@ - + diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.CoreRT.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.CoreRT.cs index 10fadea9d090be..c9239b10f4de87 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.CoreRT.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Exception.CoreRT.cs @@ -180,7 +180,7 @@ internal DispatchState CaptureDispatchState() internal void RestoreDispatchState(DispatchState DispatchState) { - IntPtr[] stackTrace = DispatchState.StackTrace; + IntPtr[]? stackTrace = DispatchState.StackTrace; int idxFirstFreeStackTraceEntry = 0; if (stackTrace != null) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs index a01d78f9f07b07..c9578dfee08036 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs @@ -83,7 +83,7 @@ public static int GetGeneration(WeakReference wo) { // note - this throws an NRE if given a null weak reference. This isn't // documented, but it's the behavior of Desktop and CoreCLR. - object handleRef = RuntimeImports.RhHandleGet(wo.m_handle); + object? handleRef = RuntimeImports.RhHandleGet(wo.m_handle); if (handleRef == null) { throw new ArgumentNullException(nameof(wo)); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs index eda6c45aa296cb..b05af345fe2960 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -31,7 +31,7 @@ protected MulticastDelegate([DynamicallyAccessedMembers(DynamicallyAccessedMembe private bool InvocationListEquals(MulticastDelegate d) { - Delegate[] invocationList = m_helperObject as Delegate[]; + Delegate[] invocationList = (Delegate[])m_helperObject; if (d.m_extraFunctionPointerOrData != m_extraFunctionPointerOrData) return false; @@ -39,7 +39,7 @@ private bool InvocationListEquals(MulticastDelegate d) for (int i = 0; i < invocationCount; i++) { Delegate dd = invocationList[i]; - Delegate[] dInvocationList = d.m_helperObject as Delegate[]; + Delegate[] dInvocationList = (Delegate[])d.m_helperObject; if (!dd.Equals(dInvocationList[i])) return false; } @@ -65,9 +65,10 @@ public override sealed bool Equals([NotNullWhen(true)] object? obj) // 1- Multicast (m_helperObject is Delegate[]) // 2- Single-cast delegate, which can be compared with a structural comparision - if (m_functionPointer == GetThunk(MulticastThunk)) + IntPtr multicastThunk = GetThunk(MulticastThunk); + if (m_functionPointer == multicastThunk) { - return InvocationListEquals(d); + return d.m_functionPointer == multicastThunk && InvocationListEquals(d); } else { @@ -280,7 +281,7 @@ protected sealed override Delegate CombineImpl(Delegate? follow) private Delegate[] DeleteFromInvocationList(Delegate[] invocationList, int invocationCount, int deleteIndex, int deleteCount) { - Delegate[] thisInvocationList = m_helperObject as Delegate[]; + Delegate[] thisInvocationList = (Delegate[])m_helperObject; int allocCount = thisInvocationList.Length; while (allocCount / 2 >= invocationCount - deleteCount) allocCount /= 2; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreRT.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreRT.cs index bcadaa56b04a05..02ebc1dfaff96c 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreRT.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreRT.cs @@ -9,8 +9,8 @@ public partial struct GCHandle private static void InternalFree(IntPtr handle) => RuntimeImports.RhHandleFree(handle); - private static object InternalGet(IntPtr handle) => RuntimeImports.RhHandleGet(handle); + private static object? InternalGet(IntPtr handle) => RuntimeImports.RhHandleGet(handle); - private static void InternalSet(IntPtr handle, object value) => RuntimeImports.RhHandleSet(handle, value); + private static void InternalSet(IntPtr handle, object? value) => RuntimeImports.RhHandleSet(handle, value); } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/PInvokeMarshal.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/PInvokeMarshal.cs index be104462e5aeb4..57a2a7c8375ef5 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/PInvokeMarshal.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/PInvokeMarshal.cs @@ -185,7 +185,7 @@ private static PInvokeDelegateThunk AllocateThunk(Delegate del) /// /// Retrieve the corresponding P/invoke instance from the stub /// - public static unsafe Delegate GetDelegateForFunctionPointer(IntPtr ptr, RuntimeTypeHandle delegateType) + public static unsafe Delegate? GetDelegateForFunctionPointer(IntPtr ptr, RuntimeTypeHandle delegateType) { if (ptr == IntPtr.Zero) return null; @@ -367,7 +367,7 @@ public static unsafe void AnsiStringToStringBuilder(byte* newBuffer, System.Text /// Input assumed to be zero terminated. Generates String.Empty for zero length string. /// This version is more efficient than ConvertToUnicode in src\Interop\System\Runtime\InteropServices\Marshal.cs in that it can skip calling /// MultiByteToWideChar for ASCII string, and it does not need another char[] buffer - public static unsafe string AnsiStringToString(byte* pchBuffer) + public static unsafe string? AnsiStringToString(byte* pchBuffer) { if (pchBuffer == null) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs index a7edbf10d819af..b0d2fad5792f37 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -245,15 +245,15 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary) // Get object reference from handle. [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhHandleGet")] - private static extern object _RhHandleGet(IntPtr handle); + private static extern object? _RhHandleGet(IntPtr handle); - internal static unsafe object RhHandleGet(IntPtr handle) + internal static unsafe object? RhHandleGet(IntPtr handle) { #if DEBUG // The runtime performs additional checks in debug builds return _RhHandleGet(handle); #else - return Unsafe.As(ref *(IntPtr*)(nint)handle); + return Unsafe.As(ref *(IntPtr*)(nint)handle); #endif } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs index f56a1cc1bfb913..9c3985b08cbe45 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs @@ -9,7 +9,7 @@ namespace System // Base class for runtime implemented Type public abstract class RuntimeType : TypeInfo { - public sealed override string GetEnumName(object value) + public sealed override string? GetEnumName(object value) { if (value == null) throw new ArgumentNullException(nameof(value)); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/WeakReference.CoreRT.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/WeakReference.CoreRT.cs index 41e765934c3013..5fc7acd35b6177 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/WeakReference.CoreRT.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/WeakReference.CoreRT.cs @@ -80,7 +80,7 @@ public virtual object? Target if (default(IntPtr) == h) return null; - object o = RuntimeImports.RhHandleGet(h); + object? o = RuntimeImports.RhHandleGet(h); if (o == null) { diff --git a/src/coreclr/pal/src/map/map.cpp b/src/coreclr/pal/src/map/map.cpp index 21ef333d437082..49ee360c4a323e 100644 --- a/src/coreclr/pal/src/map/map.cpp +++ b/src/coreclr/pal/src/map/map.cpp @@ -1604,7 +1604,7 @@ static PAL_ERROR MAPGrowLocalFile( INT UnixFD, off_t NewSize ) TruncateRetVal = ftruncate( UnixFD, NewSize ); fstat( UnixFD, &FileInfo ); - if ( TruncateRetVal != 0 || FileInfo.st_size != (int) NewSize ) + if ( TruncateRetVal != 0 || FileInfo.st_size != NewSize ) { INT OrigSize; CONST UINT BUFFER_SIZE = 128; diff --git a/src/coreclr/pal/src/misc/sysinfo.cpp b/src/coreclr/pal/src/misc/sysinfo.cpp index 8f935b3e3ea1a8..19f9c86fd451cc 100644 --- a/src/coreclr/pal/src/misc/sysinfo.cpp +++ b/src/coreclr/pal/src/misc/sysinfo.cpp @@ -613,9 +613,15 @@ PAL_GetLogicalProcessorCacheSizeFromOS() { int64_t cacheSizeFromSysctl = 0; size_t sz = sizeof(cacheSizeFromSysctl); - const bool success = sysctlbyname("hw.l3cachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0 + const bool success = false + // macOS-arm64: Since macOS 12.0, Apple added ".perflevelX." to determinate cache sizes for efficiency + // and performance cores separetely. "perflevel0" stands for "performance" + || sysctlbyname("hw.perflevel0.l2cachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0 + // macOS-arm64: these report cache sizes for efficiency cores only: + || sysctlbyname("hw.l3cachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0 || sysctlbyname("hw.l2cachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0 || sysctlbyname("hw.l1dcachesize", &cacheSizeFromSysctl, &sz, nullptr, 0) == 0; + if (success) { _ASSERTE(cacheSizeFromSysctl > 0); diff --git a/src/coreclr/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.cpp b/src/coreclr/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.cpp index 96962eda3983a7..d9e354d0f7eaea 100644 --- a/src/coreclr/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.cpp +++ b/src/coreclr/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.cpp @@ -14,13 +14,11 @@ ** WriteFile ** GetLastError ** -** **===================================================================*/ #include - #define szStringTest "The quick fox jumped over the lazy dog's back.\0" #define szEmptyString "" #define szReadableFile "Readable.txt" @@ -29,7 +27,6 @@ //Previously number of tests was 6, now 4 refer VSW 312690 #define NOOFTESTS 4 -const int PAGESIZE = 4096; char *readBuffer_ReadFile_test2; BOOL validateResults_ReadFile_test2(const char* szString, // string read @@ -66,9 +63,9 @@ BOOL readTest_ReadFile_test2(DWORD dwByteCount, char cResult) HANDLE hFile = NULL; DWORD dwBytesRead; BOOL bRc = FALSE; - - // open the test file - hFile = CreateFile(szReadableFile, + + // open the test file + hFile = CreateFile(szReadableFile, GENERIC_READ, FILE_SHARE_READ, NULL, @@ -77,12 +74,15 @@ BOOL readTest_ReadFile_test2(DWORD dwByteCount, char cResult) NULL); if(hFile == INVALID_HANDLE_VALUE) { - Trace("ReadFile: ERROR -> Unable to open file \"%s\".\n", + Trace("ReadFile: ERROR -> Unable to open file \"%s\".\n", szReadableFile); return FALSE; } - memset(readBuffer_ReadFile_test2, 0, PAGESIZE); + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + long pageSize = sysInfo.dwPageSize; + memset(readBuffer_ReadFile_test2, 0, pageSize); bRc = ReadFile(hFile, readBuffer_ReadFile_test2, dwByteCount, &dwBytesRead, NULL); @@ -94,7 +94,7 @@ BOOL readTest_ReadFile_test2(DWORD dwByteCount, char cResult) Trace("\nbRc = %d\n", bRc); Trace("readBuffer = [%s] dwByteCount = %d dwBytesRead = %d\n", readBuffer_ReadFile_test2, dwByteCount, dwBytesRead); Trace("cresult = 1\n"); - Trace("getlasterror = %d\n", GetLastError()); + Trace("getlasterror = %d\n", GetLastError()); CloseHandle(hFile); return FALSE; } @@ -121,51 +121,55 @@ BOOL readTest_ReadFile_test2(DWORD dwByteCount, char cResult) PALTEST(file_io_ReadFile_test2_paltest_readfile_test2, "file_io/ReadFile/test2/paltest_readfile_test2") { HANDLE hFile = NULL; - const int BUFFER_SIZE = 2 * PAGESIZE; - DWORD dwByteCount[] = { 0, - 10, + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + long pageSize = sysInfo.dwPageSize; + long bufferSize = 2 * pageSize; + + DWORD dwByteCount[] = { 0, + 10, strlen(szStringTest), - PAGESIZE + pageSize // Commented out two negative test cases : Refer VSW 312690 - // 2 * PAGESIZE, + // 2 * pageSize, // -1 }; DWORD oldProt; - char szResults[] = "1111"; // Was "111100": Refer VSW 312690 + char szResults[] = "1111"; // Was "111100": Refer VSW 312690 int i; BOOL bRc = FALSE; DWORD dwBytesWritten = 0; - + if (0 != PAL_Initialize(argc,argv)) { return FAIL; } /* allocate read-write memery for readBuffer */ - if (!(readBuffer_ReadFile_test2 = (char*) VirtualAlloc(NULL, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE))) + if (!(readBuffer_ReadFile_test2 = (char*) VirtualAlloc(NULL, bufferSize, MEM_COMMIT, PAGE_READWRITE))) { Fail("VirtualAlloc failed: GetLastError returns %d\n", GetLastError()); return FAIL; } - + /* write protect the second page of readBuffer */ - if (!VirtualProtect(&readBuffer_ReadFile_test2[PAGESIZE], PAGESIZE, PAGE_NOACCESS, &oldProt)) + if (!VirtualProtect(&readBuffer_ReadFile_test2[pageSize], pageSize, PAGE_NOACCESS, &oldProt)) { Fail("VirtualProtect failed: GetLastError returns %d\n", GetLastError()); return FAIL; } - // create the test file - hFile = CreateFile(szReadableFile, + // create the test file + hFile = CreateFile(szReadableFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - + if(hFile == INVALID_HANDLE_VALUE) { Fail("ReadFile: ERROR -> Unable to create file \"%s\" (%d).\n", @@ -175,7 +179,7 @@ PALTEST(file_io_ReadFile_test2_paltest_readfile_test2, "file_io/ReadFile/test2/p bRc = WriteFile(hFile, szStringTest, strlen(szStringTest), &dwBytesWritten, NULL); CloseHandle(hFile); - + for (i = 0; i< NOOFTESTS; i++) { bRc = readTest_ReadFile_test2(dwByteCount[i], szResults[i]); @@ -184,9 +188,8 @@ PALTEST(file_io_ReadFile_test2_paltest_readfile_test2, "file_io/ReadFile/test2/p Fail("ReadFile: ERROR -> Failed on test[%d]\n", i); } } - - VirtualFree(readBuffer_ReadFile_test2, BUFFER_SIZE, MEM_RELEASE); + + VirtualFree(readBuffer_ReadFile_test2, bufferSize, MEM_RELEASE); PAL_Terminate(); return PASS; } - diff --git a/src/coreclr/pal/tests/palsuite/issues.targets b/src/coreclr/pal/tests/palsuite/issues.targets index 6b0e8ae55667ad..2ed7e5b303bfca 100644 --- a/src/coreclr/pal/tests/palsuite/issues.targets +++ b/src/coreclr/pal/tests/palsuite/issues.targets @@ -31,10 +31,6 @@ - - - https://github.com/dotnet/runtime/issues/48783 - https://github.com/dotnet/runtime/issues/48783 diff --git a/src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/nopal.cpp b/src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/nopal.cpp index d226ff5cf8d82d..ff5078f85209f3 100644 --- a/src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/nopal.cpp +++ b/src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/nopal.cpp @@ -14,9 +14,6 @@ #include #include -#undef PAGE_SIZE -#define PAGE_SIZE (4096) - auto test_strcpy = strcpy; auto test_strcmp = strcmp; auto test_strlen = strlen; @@ -50,7 +47,7 @@ bool WriteHeaderInfo(const char *path, char sharedMemoryType, char version, int if (fd == -1) return false; *fdRef = fd; - if (ftruncate(fd, PAGE_SIZE) != 0) + if (ftruncate(fd, getpagesize()) != 0) return false; if (lseek(fd, 0, SEEK_SET) != 0) return false; diff --git a/src/coreclr/scripts/jitutil.py b/src/coreclr/scripts/jitutil.py index 5df464da5fc0cb..1f4306b9c34ebe 100644 --- a/src/coreclr/scripts/jitutil.py +++ b/src/coreclr/scripts/jitutil.py @@ -92,23 +92,22 @@ def set_pipeline_variable(name, value): ## ################################################################################ -def decode_string(str_to_decode): +def decode_and_print(str_to_decode): """Decode a UTF-8 encoded bytes to string. Args: str_to_decode (byte stream): Byte stream to decode Returns: - String output. If there any encoding/decoding errors, it will replace it with - UnicodeEncodeError. + String output. If there any encoding/decoding errors, it will not print anything + and return an empty string. """ + output = '' try: output = str_to_decode.decode("utf-8", errors='replace') - except UnicodeEncodeError: - output = "UnicodeEncodeError" - except UnicodeDecodeError: - output = "UnicodeDecodeError" - return output + print(output) + finally: + return output def run_command(command_to_run, _cwd=None, _exit_on_fail=False, _output_file=None): """ Runs the command. @@ -138,15 +137,14 @@ def run_command(command_to_run, _cwd=None, _exit_on_fail=False, _output_file=Non if proc.poll() is not None: break if output: - output_str = decode_string(output.strip()) - print(output_str) + output_str = decode_and_print(output.strip()) of.write(output_str + "\n") else: command_stdout, command_stderr = proc.communicate() if len(command_stdout) > 0: - print(decode_string(command_stdout)) + decode_and_print(command_stdout) if len(command_stderr) > 0: - print(decode_string(command_stderr)) + decode_and_print(command_stderr) return_code = proc.returncode if _exit_on_fail and return_code != 0: diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index 006409bdbb5338..858afde75164e2 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -86,12 +86,12 @@ static byte _getMethodInfo(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHO } [UnmanagedCallersOnly] - static CorInfoInline _canInline(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd, uint* pRestrictions) + static CorInfoInline _canInline(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd) { var _this = GetThis(thisHandle); try { - return _this.canInline(callerHnd, calleeHnd, ref *pRestrictions); + return _this.canInline(callerHnd, calleeHnd); } catch (Exception ex) { @@ -2559,7 +2559,7 @@ static IntPtr GetUnmanagedCallbacks() callbacks[2] = (delegate* unmanaged)&_setMethodAttribs; callbacks[3] = (delegate* unmanaged)&_getMethodSig; callbacks[4] = (delegate* unmanaged)&_getMethodInfo; - callbacks[5] = (delegate* unmanaged)&_canInline; + callbacks[5] = (delegate* unmanaged)&_canInline; callbacks[6] = (delegate* unmanaged)&_reportInliningDecision; callbacks[7] = (delegate* unmanaged)&_canTailCall; callbacks[8] = (delegate* unmanaged)&_reportTailCallDecision; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index cd464db7955341..41c4663ed720e2 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1159,7 +1159,7 @@ private bool getMethodInfo(CORINFO_METHOD_STRUCT_* ftn, CORINFO_METHOD_INFO* inf return Get_CORINFO_METHOD_INFO(method, methodIL, info); } - private CorInfoInline canInline(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd, ref uint pRestrictions) + private CorInfoInline canInline(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd) { MethodDesc callerMethod = HandleToObject(callerHnd); MethodDesc calleeMethod = HandleToObject(calleeHnd); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 4a7d254d583fcf..3e348263103855 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -498,16 +498,6 @@ public enum CorInfoInlineTypeCheckSource CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN = 0x00000001, // Type handle comes from an ldtoken } - public enum CorInfoInlineRestrictions - { - INLINE_RESPECT_BOUNDARY = 0x00000001, // You can inline if there are no calls from the method being inlined - INLINE_NO_CALLEE_LDSTR = 0x00000002, // You can inline only if you guarantee that if inlinee does an ldstr - // inlinee's module will never see that string (by any means). - // This is due to how we implement the NoStringInterningAttribute - // (by reusing the fixup table). - INLINE_SAME_THIS = 0x00000004, // You can inline only if the callee is on the same this reference as caller - } - // If you add more values here, keep it in sync with TailCallTypeMap in ..\vm\ClrEtwAll.man // and the string enum in CEEInfo::reportTailCallDecision in ..\vm\JITInterface.cpp public enum CorInfoTailCall diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 92bc30aaf2570b..7cccae04c4151c 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -158,7 +158,7 @@ FUNCTIONS void setMethodAttribs( CORINFO_METHOD_HANDLE ftn, CorInfoMethodRuntimeFlags attribs ); void getMethodSig( CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO *sig, CORINFO_CLASS_HANDLE memberParent ); bool getMethodInfo( CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info ); - CorInfoInline canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, uint32_t* pRestrictions ); + CorInfoInline canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd); void reportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, CorInfoInline inlineResult, const char * reason); bool canTailCall( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE declaredCalleeHnd, CORINFO_METHOD_HANDLE exactCalleeHnd, bool fIsTailPrefix ); void reportTailCallDecision(CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, bool fIsTailPrefix, CorInfoTailCall tailCallResult, const char * reason); diff --git a/src/coreclr/tools/Common/TypeSystem/Common/Utilities/LockFreeReaderHashtable.cs b/src/coreclr/tools/Common/TypeSystem/Common/Utilities/LockFreeReaderHashtable.cs index e915f9518ad043..c36e39f224859a 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/Utilities/LockFreeReaderHashtable.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/Utilities/LockFreeReaderHashtable.cs @@ -540,7 +540,7 @@ private void WriteAbortNullToLocation(TValue[] hashTableLocal, int tableIndex) // Add to hash, use a volatile write to ensure that // the contents of the value are fully published to all // threads before adding to the hashtable - Volatile.Write(ref hashTableLocal[tableIndex], null); + Volatile.Write(ref hashTableLocal[tableIndex], default(TValue)!); } [MethodImpl(MethodImplOptions.NoInlining)] diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs index 537b494b0d6f9d..2247f551fc29d1 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs @@ -535,6 +535,8 @@ public MarshalAsDescriptor ParseMarshalAsDescriptor() NativeTypeKind type = (NativeTypeKind)_reader.ReadByte(); NativeTypeKind arraySubType = NativeTypeKind.Default; uint? paramNum = null, numElem = null; + string cookie = null; + TypeDesc marshallerType = null; switch (type) { @@ -607,9 +609,6 @@ public MarshalAsDescriptor ParseMarshalAsDescriptor() break; case NativeTypeKind.CustomMarshaler: { - // There's nobody to consume CustomMarshaller, so let's just parse the data - // to avoid asserting later. - // Read typelib guid _reader.ReadSerializedString(); @@ -617,10 +616,11 @@ public MarshalAsDescriptor ParseMarshalAsDescriptor() _reader.ReadSerializedString(); // Read managed marshaler name - _reader.ReadSerializedString(); + var customMarshallerTypeName = _reader.ReadSerializedString(); + marshallerType = _ecmaModule.GetTypeByCustomAttributeTypeName(customMarshallerTypeName, true); // Read cookie - _reader.ReadSerializedString(); + cookie = _reader.ReadSerializedString(); } break; default: @@ -629,7 +629,7 @@ public MarshalAsDescriptor ParseMarshalAsDescriptor() Debug.Assert(_reader.RemainingBytes == 0); - return new MarshalAsDescriptor(type, arraySubType, paramNum, numElem); + return new MarshalAsDescriptor(type, arraySubType, paramNum, numElem, marshallerType, cookie); } } } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs index d37f44971968b7..e9a889f8233e10 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs @@ -173,6 +173,9 @@ internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type, #if !READYTORUN case MarshallerKind.Variant: return InteropTypes.GetVariant(context); + + case MarshallerKind.CustomMarshaler: + return context.GetWellKnownType(WellKnownType.IntPtr); #endif case MarshallerKind.OleCurrency: @@ -249,6 +252,14 @@ internal static MarshallerKind GetMarshallerKind( if (marshalAs != null) nativeType = marshalAs.Type; + if (nativeType == NativeTypeKind.CustomMarshaler) + { + if (isField) + return MarshallerKind.FailedTypeLoad; + else + return MarshallerKind.CustomMarshaler; + } + // // Determine MarshalerKind // @@ -574,6 +585,9 @@ internal static MarshallerKind GetMarshallerKind( case NativeTypeKind.AnsiBStr: return MarshallerKind.AnsiBSTRString; + case NativeTypeKind.CustomMarshaler: + return MarshallerKind.CustomMarshaler; + case NativeTypeKind.Default: if (isAnsi) return MarshallerKind.AnsiString; @@ -663,7 +677,9 @@ internal static MarshallerKind GetMarshallerKind( return MarshallerKind.Invalid; } else + { return MarshallerKind.Invalid; + } } private static MarshallerKind GetArrayElementMarshallerKind( @@ -834,6 +850,8 @@ private static MarshallerKind GetArrayElementMarshallerKind( return MarshallerKind.BSTRString; case NativeTypeKind.AnsiBStr: return MarshallerKind.AnsiBSTRString; + case NativeTypeKind.CustomMarshaler: + return MarshallerKind.CustomMarshaler; default: return MarshallerKind.Invalid; } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs index 01b27026152389..cd1395d9115b56 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs @@ -90,6 +90,8 @@ protected static Marshaller CreateMarshaller(MarshallerKind kind) return new FailedTypeLoadMarshaller(); case MarshallerKind.Variant: return new VariantMarshaller(); + case MarshallerKind.CustomMarshaler: + return new CustomTypeMarshaller(); default: // ensures we don't throw during create marshaller. We will throw NSE // during EmitIL which will be handled and an Exception method body @@ -1144,4 +1146,136 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); } } + + class CustomTypeMarshaller : Marshaller + { + private ILLocalVariable MarshallerLocalVariable = (ILLocalVariable)(-1); + + private ILLocalVariable InitializeMarshallerVariable() + { + if (MarshallerLocalVariable != (ILLocalVariable)(-1)) + { + return MarshallerLocalVariable; + } + + var marshallerType = MarshalAsDescriptor.MarshallerType; + if (marshallerType.IsGenericDefinition) + { + ThrowHelper.ThrowTypeLoadException(marshallerType); + } + + var customMarshallerType = Context.SystemModule.GetKnownType("System.Runtime.InteropServices", "ICustomMarshaler"); + var getInstanceMethod = marshallerType.GetMethod( + "GetInstance", + new MethodSignature(MethodSignatureFlags.Static, 0, customMarshallerType, new[] { Context.GetWellKnownType(WellKnownType.String) })); + if (ManagedType.IsValueType || ManagedType.IsPointer || ManagedType.IsFunctionPointer) + { + ThrowHelper.ThrowMarshalDirectiveException(); + } + + var initializeCustomMarshallerMethod = Context.GetHelperEntryPoint("InteropHelpers", "InitializeCustomMarshaller"); + + ILEmitter emitter = _ilCodeStreams.Emitter; + MarshallerLocalVariable = emitter.NewLocal(customMarshallerType); + var cookie = MarshalAsDescriptor.Cookie; + + // Custom marshaller initialization should not be catched, so initialize early + ILCodeStream fnptrLoadStream = _ilCodeStreams.FunctionPointerLoadStream; + fnptrLoadStream.Emit(ILOpcode.ldtoken, emitter.NewToken(ManagedType)); + fnptrLoadStream.Emit(ILOpcode.ldtoken, emitter.NewToken(marshallerType)); + fnptrLoadStream.Emit(ILOpcode.ldstr, emitter.NewToken(cookie)); + if (getInstanceMethod != null) + { + fnptrLoadStream.Emit(ILOpcode.ldftn, emitter.NewToken(getInstanceMethod)); + } + else + { + fnptrLoadStream.EmitLdc(0); + fnptrLoadStream.Emit(ILOpcode.conv_i); + } + + fnptrLoadStream.Emit(ILOpcode.call, emitter.NewToken(initializeCustomMarshallerMethod)); + fnptrLoadStream.EmitStLoc(MarshallerLocalVariable); + return MarshallerLocalVariable; + } + + protected override void TransformManagedToNative(ILCodeStream codeStream) + { + var lMarshaller = InitializeMarshallerVariable(); + + var customMarshallerType = Context.SystemModule.GetKnownType("System.Runtime.InteropServices", "ICustomMarshaler"); + ILEmitter emitter = _ilCodeStreams.Emitter; + var manageToNativeMethod = customMarshallerType.GetKnownMethod( + "MarshalManagedToNative", + new MethodSignature(MethodSignatureFlags.None, 0, Context.GetWellKnownType(WellKnownType.IntPtr), new[] { Context.GetWellKnownType(WellKnownType.Object) })); + + codeStream.EmitLdLoc(lMarshaller); + LoadManagedValue(codeStream); + codeStream.Emit(ILOpcode.callvirt, emitter.NewToken(manageToNativeMethod)); + StoreNativeValue(codeStream); + if (MarshalDirection == MarshalDirection.Forward) + { + if (In && Out) + { + EmitCleanUpManagedData(codeStream); + } + + EmitCleanUpNativeData(_ilCodeStreams.CleanupCodeStream); + } + else + { + EmitCleanUpManagedData(codeStream); + } + } + + protected override void TransformNativeToManaged(ILCodeStream codeStream) + { + var lMarshaller = InitializeMarshallerVariable(); + + var customMarshallerType = Context.SystemModule.GetKnownType("System.Runtime.InteropServices", "ICustomMarshaler"); + ILEmitter emitter = _ilCodeStreams.Emitter; + var marshalNativeToManagedMethod = customMarshallerType.GetKnownMethod( + "MarshalNativeToManaged", + new MethodSignature(MethodSignatureFlags.None, 0, Context.GetWellKnownType(WellKnownType.Object), new[] { Context.GetWellKnownType(WellKnownType.IntPtr) })); + + codeStream.EmitLdLoc(lMarshaller); + LoadNativeValue(codeStream); + codeStream.Emit(ILOpcode.callvirt, emitter.NewToken(marshalNativeToManagedMethod)); + StoreManagedValue(codeStream); + } + + protected void EmitCleanUpManagedData(ILCodeStream codeStream) + { + var lMarshaller = InitializeMarshallerVariable(); + + var customMarshallerType = Context.SystemModule.GetKnownType("System.Runtime.InteropServices", "ICustomMarshaler"); + ILEmitter emitter = _ilCodeStreams.Emitter; + + // Call CleanUpManagedData on cleanup code stream. + var cleanupManagedDataMethod = customMarshallerType.GetKnownMethod( + "CleanUpManagedData", + new MethodSignature(MethodSignatureFlags.None, 0, Context.GetWellKnownType(WellKnownType.Void), new[] { Context.GetWellKnownType(WellKnownType.Object) })); + + codeStream.EmitLdLoc(lMarshaller); + LoadManagedValue(codeStream); + codeStream.Emit(ILOpcode.callvirt, emitter.NewToken(cleanupManagedDataMethod)); + } + + protected void EmitCleanUpNativeData(ILCodeStream codeStream) + { + var lMarshaller = InitializeMarshallerVariable(); + + var customMarshallerType = Context.SystemModule.GetKnownType("System.Runtime.InteropServices", "ICustomMarshaler"); + ILEmitter emitter = _ilCodeStreams.Emitter; + + // Call CleanUpNativeData on cleanup code stream. + var cleanupNativeDataMethod = customMarshallerType.GetKnownMethod( + "CleanUpNativeData", + new MethodSignature(MethodSignatureFlags.None, 0, Context.GetWellKnownType(WellKnownType.Void), new[] { Context.GetWellKnownType(WellKnownType.IntPtr) })); + + codeStream.EmitLdLoc(lMarshaller); + LoadNativeValue(codeStream); + codeStream.Emit(ILOpcode.callvirt, emitter.NewToken(cleanupNativeDataMethod)); + } + } } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshallerKind.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshallerKind.cs index 888a174ff38fcc..8d4fb58a45d191 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshallerKind.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshallerKind.cs @@ -48,6 +48,7 @@ enum MarshallerKind FailedTypeLoad, ComInterface, BlittableValueClassWithCopyCtor, + CustomMarshaler, Invalid } diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs b/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs index 91f3c9d2fe0773..c76e2cf469350d 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs @@ -3,6 +3,7 @@ using System.Runtime.CompilerServices; using System; +using System.Diagnostics; namespace Internal.TypeSystem { @@ -48,17 +49,39 @@ public enum NativeTypeKind : byte public class MarshalAsDescriptor { + private TypeDesc _marshallerType; + private string _cookie; + public NativeTypeKind Type { get; } public NativeTypeKind ArraySubType { get; } public uint? SizeParamIndex { get; } public uint? SizeConst { get; } + public TypeDesc MarshallerType + { + get + { + Debug.Assert(Type == NativeTypeKind.CustomMarshaler, "Marshaller type can be set only when using for CustomMarshaller"); + return _marshallerType; + } + } + + public string Cookie + { + get + { + Debug.Assert(Type == NativeTypeKind.CustomMarshaler, "Cookie can be set only when using for CustomMarshaller"); + return _cookie; + } + } - public MarshalAsDescriptor(NativeTypeKind type, NativeTypeKind arraySubType, uint? sizeParamIndex, uint? sizeConst) + public MarshalAsDescriptor(NativeTypeKind type, NativeTypeKind arraySubType, uint? sizeParamIndex, uint? sizeConst, TypeDesc customMarshallerType, string cookie) { Type = type; ArraySubType = arraySubType; SizeParamIndex = sizeParamIndex; SizeConst = sizeConst; + _marshallerType = customMarshallerType; + _cookie = cookie; } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs index 1f462113d8e0c4..44eada8ff9ae68 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs @@ -142,7 +142,6 @@ protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bo } else { - ISymbolNode targetMethodNode = target.GetTargetNode(factory); encoder.EmitMOV(encoder.TargetRegister.Arg2, target.GetTargetNode(factory)); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs index 0b9068e3a13f24..3574e998d8fa1d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs @@ -147,7 +147,6 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder, } else { - ISymbolNode targetMethodNode = target.GetTargetNode(factory); encoder.EmitMOV(encoder.TargetRegister.Arg2, target.GetTargetNode(factory)); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs index 07ab13b13d2c70..2c80e0b0faafba 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs @@ -150,7 +150,6 @@ protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bo } else { - ISymbolNode targetMethodNode = target.GetTargetNode(factory); encoder.EmitLEAQ(encoder.TargetRegister.Arg2, target.GetTargetNode(factory)); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs index ae9e60343dfb42..23a2af0219da7c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs @@ -270,7 +270,7 @@ internal override VTableSliceNode GetSlice(TypeDesc type) { if (!_vtableSlices.TryGetValue(type, out IReadOnlyList slots)) { - // If we couln't find the vtable slice information for this type, it's because the scanner + // If we couldn't find the vtable slice information for this type, it's because the scanner // didn't correctly predict what will be needed. // To troubleshoot, compare the dependency graph of the scanner and the compiler. // Follow the path from the node that requested this node to the root. @@ -318,7 +318,7 @@ private DictionaryLayoutNode GetPrecomputedLayout(TypeSystemEntity methodOrType) { if (!_layouts.TryGetValue(methodOrType, out IEnumerable layout)) { - // If we couln't find the dictionary layout information for this, it's because the scanner + // If we couldn't find the dictionary layout information for this, it's because the scanner // didn't correctly predict what will be needed. // To troubleshoot, compare the dependency graph of the scanner and the compiler. // Follow the path from the node that requested this node to the root. diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs index ca81bd42d8e4c2..6ce9159a12dafd 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs @@ -261,17 +261,43 @@ private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record) record.PackingSize = checked((ushort)layoutMetadata.PackingSize); record.Flags = GetTypeAttributes(entity); - if (entity.HasBaseType) + try { - record.BaseType = HandleType(entity.BaseType); + if (entity.HasBaseType) + { + record.BaseType = HandleType(entity.BaseType); + } + } + catch (Cts.TypeSystemException) when (HasNestedTypes(entity)) + { + // We might have been forced to generate metadata for a type + // that wasn't looked at during code generation because it's an owning + // type of a type we did look at. Allow those to generate incomplete + // metadata. The ultimate fix is to rewrite metadata generation to be + // System.Reflection.Metadata-based as opposed to type system based. + // If there's no nested types, this is a bug and should tear down + // the compiler at this point. } - record.Interfaces.Capacity = entity.ExplicitlyImplementedInterfaces.Length; - foreach (var interfaceType in entity.ExplicitlyImplementedInterfaces) + try + { + record.Interfaces.Capacity = entity.ExplicitlyImplementedInterfaces.Length; + foreach (var interfaceType in entity.ExplicitlyImplementedInterfaces) + { + if (IsBlocked(interfaceType)) + continue; + record.Interfaces.Add(HandleType(interfaceType)); + } + } + catch (Cts.TypeSystemException) when (HasNestedTypes(entity)) { - if (IsBlocked(interfaceType)) - continue; - record.Interfaces.Add(HandleType(interfaceType)); + // We might have been forced to generate metadata for a type + // that wasn't looked at during code generation because it's an owning + // type of a type we did look at. Allow those to generate incomplete + // metadata. The ultimate fix is to rewrite metadata generation to be + // System.Reflection.Metadata-based as opposed to type system based. + // If there's no nested types, this is a bug and should tear down + // the compiler at this point. } if (entity.HasInstantiation) @@ -346,6 +372,9 @@ private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record) record.MethodImpls.Add(methodImplRecord); }*/ } + + static bool HasNestedTypes(Cts.MetadataType entity) + => entity.GetNestedTypes().GetEnumerator().MoveNext(); } private TypeAttributes GetTypeAttributes(Cts.MetadataType type) diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 4eab54b43b8628..c732d55ef2546a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -1072,7 +1072,12 @@ private void ParsePgoMethods() PgoInfoKey key = new PgoInfoKey(mdReader, owningType, methodHandle, methodTypeArgs); PgoInfo info = new PgoInfo(key, this, pgoFormatVersion, Image, pgoOffset); - _pgoInfos.Add(key, info); + + // Since we do non-assembly qualified name based matching for generic instantiations, we can have conflicts. + // This is rare, so the current strategy is to just ignore them. This will allow the tooling to work, although + // the text output for PGO will be slightly wrong. + if (!_pgoInfos.ContainsKey(key)) + _pgoInfos.Add(key, info); curParser = allEntriesEnum.GetNext(); } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs index 7e2b624a3131fc..839626e6d5d9e8 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs @@ -210,7 +210,7 @@ private void CompileSingleMethod(CorInfoImpl corInfo, MethodCodeNode methodCodeN Logger.LogWarning(method, DiagnosticId.COMInteropNotSupportedInFullAOT); } if ((_compilationOptions & RyuJitCompilationOptions.UseResilience) != 0) - Logger.LogMessage($"Ignoring unresolved method {method}, because: {exception.Message}"); + Logger.LogMessage($"Method '{method}' will always throw because: {exception.Message}"); else Logger.LogError($"Method will always throw because: {exception.Message}", 1005, method, MessageSubCategory.AotAnalysis); } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs index a1446f9d3ff274..bc29c680363f04 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs @@ -22,6 +22,7 @@ public sealed class RyuJitCompilationBuilder : CompilationBuilder private KeyValuePair[] _ryujitOptions = Array.Empty>(); private ILProvider _ilProvider = new CoreRTILProvider(); private ProfileDataManager _profileDataManager; + private string _jitPath; public RyuJitCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group) : base(context, group, @@ -35,6 +36,12 @@ public RyuJitCompilationBuilder UseProfileData(IEnumerable mibcFiles) return this; } + public RyuJitCompilationBuilder UseJitPath(string jitPath) + { + _jitPath = jitPath; + return this; + } + public override CompilationBuilder UseBackendOptions(IEnumerable options) { var builder = new ArrayBuilder>(); @@ -118,7 +125,7 @@ public override ICompilation ToCompilation() var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, _interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider, GetPreinitializationManager()); - JitConfigProvider.Initialize(_context.Target, jitFlagBuilder.ToArray(), _ryujitOptions); + JitConfigProvider.Initialize(_context.Target, jitFlagBuilder.ToArray(), _ryujitOptions, _jitPath); DependencyAnalyzerBase graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(new CompilerComparer())); return new RyuJitCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _devirtualizationManager, _inliningPolicy ?? _compilationGroup, _instructionSetSupport, _profileDataManager, _methodImportationErrorProvider, options, _parallelism); } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 1b1fbdf550777d..4706aaa7f7901c 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -748,8 +748,17 @@ private bool canTailCall(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUC private InfoAccessType constructStringLiteral(CORINFO_MODULE_STRUCT_* module, mdToken metaTok, ref void* ppValue) { MethodIL methodIL = (MethodIL)HandleToObject((IntPtr)module); - object literal = methodIL.GetObject((int)metaTok); - ISymbolNode stringObject = _compilation.NodeFactory.SerializedStringObject((string)literal); + + ISymbolNode stringObject; + if (metaTok == (mdToken)CorConstants.CorTokenType.mdtString) + { + stringObject = _compilation.NodeFactory.SerializedStringObject(""); + } + else + { + object literal = methodIL.GetObject((int)metaTok); + stringObject = _compilation.NodeFactory.SerializedStringObject((string)literal); + } ppValue = (void*)ObjectToHandle(stringObject); return stringObject.RepresentsIndirectionCell ? InfoAccessType.IAT_PVALUE : InfoAccessType.IAT_VALUE; } diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs index 51400a9e939be0..94bfbcc86e848a 100644 --- a/src/coreclr/tools/aot/ILCompiler/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/Program.cs @@ -62,6 +62,7 @@ internal class Program private string _guard; private int _maxGenericCycle = CompilerTypeSystemContext.DefaultGenericCycleCutoffPoint; private bool _useDwarf5; + private string _jitPath; private string _singleMethodTypeName; private string _singleMethodName; @@ -230,6 +231,7 @@ private ArgumentSyntax ParseCommandLine(string[] args) syntax.DefineOption("targetarch", ref _targetArchitectureStr, "Target architecture for cross compilation"); syntax.DefineOption("targetos", ref _targetOSStr, "Target OS for cross compilation"); + syntax.DefineOption("jitpath", ref _jitPath, "Path to JIT compiler library"); syntax.DefineOption("singlemethodtypename", ref _singleMethodTypeName, "Single method compilation: assembly-qualified name of the owning type"); syntax.DefineOption("singlemethodname", ref _singleMethodName, "Single method compilation: name of the method"); @@ -642,6 +644,8 @@ static string ILLinkify(string rootedAssembly) if (_mibcFilePaths.Count > 0) ((RyuJitCompilationBuilder)builder).UseProfileData(_mibcFilePaths); + if (!String.IsNullOrEmpty(_jitPath)) + ((RyuJitCompilationBuilder)builder).UseJitPath(_jitPath); PInvokeILEmitterConfiguration pinvokePolicy = new ConfigurablePInvokePolicy(typeSystemContext.Target, _directPInvokes, _directPInvokeLists); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index 14286588063b23..9f802bdb461836 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -16,7 +16,7 @@ struct JitInterfaceCallbacks void (* setMethodAttribs)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, CorInfoMethodRuntimeFlags attribs); void (* getMethodSig)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent); bool (* getMethodInfo)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info); - CorInfoInline (* canInline)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, uint32_t* pRestrictions); + CorInfoInline (* canInline)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd); void (* reportInliningDecision)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, CorInfoInline inlineResult, const char* reason); bool (* canTailCall)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE declaredCalleeHnd, CORINFO_METHOD_HANDLE exactCalleeHnd, bool fIsTailPrefix); void (* reportTailCallDecision)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, bool fIsTailPrefix, CorInfoTailCall tailCallResult, const char* reason); @@ -247,11 +247,10 @@ class JitInterfaceWrapper : public ICorJitInfo virtual CorInfoInline canInline( CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE calleeHnd, - uint32_t* pRestrictions) + CORINFO_METHOD_HANDLE calleeHnd) { CorInfoExceptionClass* pException = nullptr; - CorInfoInline temp = _callbacks->canInline(_thisHandle, &pException, callerHnd, calleeHnd, pRestrictions); + CorInfoInline temp = _callbacks->canInline(_thisHandle, &pException, callerHnd, calleeHnd); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h index fd2a35093c7dec..1cd8a06b0aa277 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h @@ -66,7 +66,6 @@ struct DLDL struct Agnostic_CanInline { - DWORD Restrictions; DWORD result; DWORD exceptionCode; }; diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index ab8717dae42e80..21526c49fb5f4d 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -1293,7 +1293,6 @@ LPCWSTR MethodContext::repGetJitTimeLogFilename() void MethodContext::recCanInline(CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, - uint32_t* pRestrictions, CorInfoInline response, DWORD exceptionCode) { @@ -1306,10 +1305,6 @@ void MethodContext::recCanInline(CORINFO_METHOD_HANDLE callerHnd, key.B = CastHandle(calleeHnd); Agnostic_CanInline value; - if (pRestrictions != nullptr) - value.Restrictions = (DWORD)*pRestrictions; - else - value.Restrictions = (DWORD)0; value.result = (DWORD)response; value.exceptionCode = (DWORD)exceptionCode; @@ -1318,12 +1313,11 @@ void MethodContext::recCanInline(CORINFO_METHOD_HANDLE callerHnd, } void MethodContext::dmpCanInline(DLDL key, const Agnostic_CanInline& value) { - printf("CanInline key - callerHnd-%016llX calleeHnd-%016llX, value pRestrictions-%u result-%u exceptionCode-%08X", - key.A, key.B, value.Restrictions, value.result, value.exceptionCode); + printf("CanInline key - callerHnd-%016llX calleeHnd-%016llX, value result-%u exceptionCode-%08X", + key.A, key.B, value.result, value.exceptionCode); } CorInfoInline MethodContext::repCanInline(CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, - uint32_t* pRestrictions, DWORD* exceptionCode) { DLDL key; @@ -1347,8 +1341,6 @@ CorInfoInline MethodContext::repCanInline(CORINFO_METHOD_HANDLE callerHnd, *exceptionCode = value.exceptionCode; - if (pRestrictions != nullptr) - *pRestrictions = (DWORD)value.Restrictions; CorInfoInline response = (CorInfoInline)value.result; return response; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index d18c531dd86483..dc2e733e343fe7 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -193,13 +193,11 @@ class MethodContext void recCanInline(CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, - uint32_t* pRestrictions, CorInfoInline response, DWORD exceptionCode); void dmpCanInline(DLDL key, const Agnostic_CanInline& value); CorInfoInline repCanInline(CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, - uint32_t* pRestrictions, DWORD* exceptionCode); void recResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD exceptionCode); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 061d3d6a77b927..f347a616f96f4c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -89,17 +89,14 @@ bool interceptor_ICJI::getMethodInfo(CORINFO_METHOD_HANDLE ftn, /* IN */ } // Decides if you have any limitations for inlining. If everything's OK, it will return -// INLINE_PASS and will fill out pRestrictions with a mask of restrictions the caller of this -// function must respect. If caller passes pRestrictions = nullptr, if there are any restrictions -// INLINE_FAIL will be returned +// INLINE_PASS. // // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls) // // The inlined method need not be verified CorInfoInline interceptor_ICJI::canInline(CORINFO_METHOD_HANDLE callerHnd, /* IN */ - CORINFO_METHOD_HANDLE calleeHnd, /* IN */ - uint32_t* pRestrictions /* OUT */ + CORINFO_METHOD_HANDLE calleeHnd /* IN */ ) { CorInfoInline temp = INLINE_NEVER; @@ -108,11 +105,11 @@ CorInfoInline interceptor_ICJI::canInline(CORINFO_METHOD_HANDLE callerHnd, /* [&]() { mc->cr->AddCall("canInline"); - temp = original_ICorJitInfo->canInline(callerHnd, calleeHnd, pRestrictions); + temp = original_ICorJitInfo->canInline(callerHnd, calleeHnd); }, [&](DWORD exceptionCode) { - this->mc->recCanInline(callerHnd, calleeHnd, pRestrictions, temp, exceptionCode); + this->mc->recCanInline(callerHnd, calleeHnd, temp, exceptionCode); }); return temp; diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 657575cce71fe3..66f792968885d8 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -53,11 +53,10 @@ bool interceptor_ICJI::getMethodInfo( CorInfoInline interceptor_ICJI::canInline( CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE calleeHnd, - uint32_t* pRestrictions) + CORINFO_METHOD_HANDLE calleeHnd) { mcs->AddCall("canInline"); - return original_ICorJitInfo->canInline(callerHnd, calleeHnd, pRestrictions); + return original_ICorJitInfo->canInline(callerHnd, calleeHnd); } void interceptor_ICJI::reportInliningDecision( diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 294750ccde5c1a..cd38c2c7759390 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -48,10 +48,9 @@ bool interceptor_ICJI::getMethodInfo( CorInfoInline interceptor_ICJI::canInline( CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE calleeHnd, - uint32_t* pRestrictions) + CORINFO_METHOD_HANDLE calleeHnd) { - return original_ICorJitInfo->canInline(callerHnd, calleeHnd, pRestrictions); + return original_ICorJitInfo->canInline(callerHnd, calleeHnd); } void interceptor_ICJI::reportInliningDecision( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 16c66a6a398476..d90f0b5e097068 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -81,23 +81,20 @@ bool MyICJI::getMethodInfo(CORINFO_METHOD_HANDLE ftn, /* IN */ } // Decides if you have any limitations for inlining. If everything's OK, it will return -// INLINE_PASS and will fill out pRestrictions with a mask of restrictions the caller of this -// function must respect. If caller passes pRestrictions = nullptr, if there are any restrictions -// INLINE_FAIL will be returned +// INLINE_PASS. // // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls) // // The inlined method need not be verified CorInfoInline MyICJI::canInline(CORINFO_METHOD_HANDLE callerHnd, /* IN */ - CORINFO_METHOD_HANDLE calleeHnd, /* IN */ - uint32_t* pRestrictions /* OUT */ + CORINFO_METHOD_HANDLE calleeHnd /* IN */ ) { jitInstance->mc->cr->AddCall("canInline"); DWORD exceptionCode = 0; - CorInfoInline result = jitInstance->mc->repCanInline(callerHnd, calleeHnd, pRestrictions, &exceptionCode); + CorInfoInline result = jitInstance->mc->repCanInline(callerHnd, calleeHnd, &exceptionCode); if (exceptionCode != 0) ThrowException(exceptionCode); return result; diff --git a/src/coreclr/utilcode/stresslog.cpp b/src/coreclr/utilcode/stresslog.cpp index 5d13b2ec7695ca..0d6f4cd53c93f0 100644 --- a/src/coreclr/utilcode/stresslog.cpp +++ b/src/coreclr/utilcode/stresslog.cpp @@ -965,6 +965,19 @@ void* __cdecl ThreadStressLog::operator new(size_t n, const NoThrow&) NOEXCEPT return malloc(n); #endif //HOST_WINDOWS } + +void __cdecl ThreadStressLog::operator delete(void* p) +{ + if (StressLogChunk::s_memoryMapped) + return; // Giving up, we will just leak it instead of building a sophisticated allocator +#ifdef HOST_WINDOWS + _ASSERTE(StressLogChunk::s_LogChunkHeap); + HeapFree(StressLogChunk::s_LogChunkHeap, 0, p); +#else + free(p); +#endif //HOST_WINDOWS +} + #endif //MEMORY_MAPPED_STRESSLOG #endif // STRESS_LOG diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index c25b7aa19cc9d1..5344eb22dc9144 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -432,7 +432,7 @@ void Module::SetNativeMetadataAssemblyRefInCache(DWORD rid, PTR_Assembly pAssemb _ASSERTE(m_NativeMetadataAssemblyRefMap != NULL); _ASSERTE(rid <= GetNativeMetadataAssemblyCount()); - m_NativeMetadataAssemblyRefMap[rid - 1] = pAssembly; + VolatileStore(&m_NativeMetadataAssemblyRefMap[rid - 1], pAssembly); } // Module initialization occurs in two phases: the constructor phase and the Initialize phase. @@ -1596,75 +1596,6 @@ InstrumentedILOffsetMapping Module::GetInstrumentedILOffsetMapping(mdMethodDef t #ifndef DACCESS_COMPILE - -BOOL Module::IsNoStringInterning() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - } - CONTRACTL_END - - if (!(m_dwPersistedFlags & COMPUTED_STRING_INTERNING)) - { - // Default is string interning - BOOL fNoStringInterning = FALSE; - - HRESULT hr; - - IMDInternalImport *mdImport = GetAssembly()->GetMDImport(); - _ASSERTE(mdImport); - - mdToken token; - IfFailThrow(mdImport->GetAssemblyFromScope(&token)); - - const BYTE *pVal; - ULONG cbVal; - - hr = mdImport->GetCustomAttributeByName(token, - COMPILATIONRELAXATIONS_TYPE, - (const void**)&pVal, &cbVal); - - // Parse the attribute - if (hr == S_OK) - { - CustomAttributeParser cap(pVal, cbVal); - IfFailThrow(cap.SkipProlog()); - - // Get Flags - UINT32 flags; - IfFailThrow(cap.GetU4(&flags)); - - if (flags & CompilationRelaxations_NoStringInterning) - { - fNoStringInterning = TRUE; - } - } - -#ifdef _DEBUG - static ConfigDWORD g_NoStringInterning; - DWORD dwOverride = g_NoStringInterning.val(CLRConfig::INTERNAL_NoStringInterning); - - if (dwOverride == 0) - { - // Disabled - fNoStringInterning = FALSE; - } - else if (dwOverride == 2) - { - // Always true (testing) - fNoStringInterning = TRUE; - } -#endif // _DEBUG - - FastInterlockOr(&m_dwPersistedFlags, COMPUTED_STRING_INTERNING | - (fNoStringInterning ? NO_STRING_INTERNING : 0)); - } - - return !!(m_dwPersistedFlags & NO_STRING_INTERNING); -} - BOOL Module::HasDefaultDllImportSearchPathsAttribute() { CONTRACTL @@ -3102,7 +3033,7 @@ void Module::InitializeStringData(DWORD token, EEStringData *pstrData, CQuickByt } -OBJECTHANDLE Module::ResolveStringRef(DWORD token, BaseDomain *pDomain, bool bNeedToSyncWithFixups) +OBJECTHANDLE Module::ResolveStringRef(DWORD token, BaseDomain *pDomain) { CONTRACTL { diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index d9cd6742cb6c0e..a97be226fb9fba 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -805,9 +805,8 @@ class Module // unused = 0x00000001, COMPUTED_GLOBAL_CLASS = 0x00000002, - // This flag applies to assembly, but it is stored so it can be cached in ngen image - COMPUTED_STRING_INTERNING = 0x00000004, - NO_STRING_INTERNING = 0x00000008, + // unused = 0x00000004, + // unused = 0x00000008, // This flag applies to assembly, but it is stored so it can be cached in ngen image COMPUTED_WRAP_EXCEPTIONS = 0x00000010, @@ -1400,7 +1399,7 @@ class Module void InitializeStringData(DWORD token, EEStringData *pstrData, CQuickBytes *pqb); // Resolving - OBJECTHANDLE ResolveStringRef(DWORD Token, BaseDomain *pDomain, bool bNeedToSyncWithFixups); + OBJECTHANDLE ResolveStringRef(DWORD Token, BaseDomain *pDomain); CHECK CheckStringRef(RVA rva); @@ -2024,13 +2023,6 @@ class Module public: - //----------------------------------------------------------------------------------------- - // If true, strings only need to be interned at a per module basis, instead of at a - // per appdomain basis, which is the default. Use the module accessor so you don't need - // to touch the metadata in the ngen case - //----------------------------------------------------------------------------------------- - BOOL IsNoStringInterning(); - //----------------------------------------------------------------------------------------- // Returns a BOOL to indicate if we have computed whether compiler has instructed us to // wrap the non-CLS compliant exceptions or not. diff --git a/src/coreclr/vm/common.h b/src/coreclr/vm/common.h index c2fff3f9c9a961..eb37c0a0cac94b 100644 --- a/src/coreclr/vm/common.h +++ b/src/coreclr/vm/common.h @@ -119,7 +119,7 @@ typedef DPTR(class ComCallMethodDesc) PTR_ComCallMethodDesc; typedef DPTR(class ComPlusCallMethodDesc) PTR_ComPlusCallMethodDesc; typedef VPTR(class DebugInterface) PTR_DebugInterface; typedef DPTR(class Dictionary) PTR_Dictionary; -typedef VPTR(class DomainAssembly) PTR_DomainAssembly; +typedef DPTR(class DomainAssembly) PTR_DomainAssembly; typedef DPTR(struct FailedAssembly) PTR_FailedAssembly; typedef VPTR(class EditAndContinueModule) PTR_EditAndContinueModule; typedef DPTR(class EEClass) PTR_EEClass; diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 919a5352c1bb0a..54f17064fcad43 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -113,13 +113,6 @@ DEFINE_FIELD(ARRAY_WITH_OFFSET, M_ARRAY, m_array) DEFINE_FIELD(ARRAY_WITH_OFFSET, M_OFFSET, m_offset) DEFINE_FIELD(ARRAY_WITH_OFFSET, M_COUNT, m_count) - -DEFINE_CLASS(ASSEMBLY_BUILDER, ReflectionEmit, AssemblyBuilder) -DEFINE_CLASS(INTERNAL_ASSEMBLY_BUILDER, ReflectionEmit, InternalAssemblyBuilder) -#if FOR_ILLINK -DEFINE_METHOD(INTERNAL_ASSEMBLY_BUILDER, CTOR, .ctor, IM_RetVoid) -#endif - DEFINE_CLASS(ASSEMBLY_HASH_ALGORITHM, Assemblies, AssemblyHashAlgorithm) DEFINE_CLASS(PORTABLE_EXECUTABLE_KINDS, Reflection, PortableExecutableKinds) DEFINE_CLASS(IMAGE_FILE_MACHINE, Reflection, ImageFileMachine) @@ -582,10 +575,6 @@ DEFINE_FIELD_U(m_pFields, ReflectModuleBaseObject, m_pGloba DEFINE_CLASS(MODULE, Reflection, RuntimeModule) DEFINE_FIELD(MODULE, DATA, m_pData) -DEFINE_CLASS(MODULE_BUILDER, ReflectionEmit, InternalModuleBuilder) -#if FOR_ILLINK -DEFINE_METHOD(MODULE_BUILDER, CTOR, .ctor, IM_RetVoid) -#endif DEFINE_CLASS(TYPE_BUILDER, ReflectionEmit, TypeBuilder) DEFINE_CLASS(ENUM_BUILDER, ReflectionEmit, EnumBuilder) diff --git a/src/coreclr/vm/domainassembly.cpp b/src/coreclr/vm/domainassembly.cpp index 458f988280b02d..b8b19bb08b1694 100644 --- a/src/coreclr/vm/domainassembly.cpp +++ b/src/coreclr/vm/domainassembly.cpp @@ -353,14 +353,7 @@ OBJECTREF DomainAssembly::GetExposedModuleObject() GCPROTECT_BEGIN(refClass); - if (GetPEAssembly()->IsDynamic()) - { - refClass = (REFLECTMODULEBASEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__MODULE_BUILDER)); - } - else - { - refClass = (REFLECTMODULEBASEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__MODULE)); - } + refClass = (REFLECTMODULEBASEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__MODULE)); refClass->SetModule(m_pModule); // Attach the reference to the assembly to keep the LoaderAllocator for this collectible type @@ -672,18 +665,8 @@ OBJECTREF DomainAssembly::GetExposedAssemblyObject() { ASSEMBLYREF assemblyObj = NULL; MethodTable * pMT; - if (GetPEAssembly()->IsDynamic()) - { - // This is unnecessary because the managed InternalAssemblyBuilder object - // should have already been created at the time of DefineDynamicAssembly - OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); - pMT = CoreLibBinder::GetClass(CLASS__INTERNAL_ASSEMBLY_BUILDER); - } - else - { - OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); - pMT = CoreLibBinder::GetClass(CLASS__ASSEMBLY); - } + + pMT = CoreLibBinder::GetClass(CLASS__ASSEMBLY); // Will be TRUE only if LoaderAllocator managed object was already collected and therefore we should // return NULL diff --git a/src/coreclr/vm/field.cpp b/src/coreclr/vm/field.cpp index 3855f4a22c0df7..31d858814d020c 100644 --- a/src/coreclr/vm/field.cpp +++ b/src/coreclr/vm/field.cpp @@ -97,6 +97,14 @@ BOOL FieldDesc::IsObjRef() return CorTypeInfo::IsObjRef_NoThrow(GetFieldType()); } +// Return whether the field is a GC ref type +BOOL FieldDesc::IsByRef() +{ + WRAPPER_NO_CONTRACT; + SUPPORTS_DAC; + return CorTypeInfo::IsByRef_NoThrow(GetFieldType()); +} + BOOL FieldDesc::MightHaveName(ULONG nameHashValue) { LIMITED_METHOD_CONTRACT; diff --git a/src/coreclr/vm/field.h b/src/coreclr/vm/field.h index 25e9e19fb7306a..72378df259060a 100644 --- a/src/coreclr/vm/field.h +++ b/src/coreclr/vm/field.h @@ -353,6 +353,8 @@ class FieldDesc BOOL IsObjRef(); + BOOL IsByRef(); + UINT LoadSize(); // Return -1 if the type isn't loaded yet (i.e. if LookupFieldTypeHandle() would return null) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 27d2452491e2a1..cd8ab0933e9229 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -2433,7 +2433,7 @@ OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken meta _ASSERTE(TypeFromToken(metaTok) == mdtString); Module* module = GetModule(scopeHnd); - return module->ResolveStringRef(metaTok, module->GetAssembly()->Parent(), false); + return module->ResolveStringRef(metaTok, module->GetAssembly()->Parent()); } /*********************************************************************/ diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 3a9f5c0207a6bb..69a0abdfcb1efb 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2029,54 +2029,54 @@ bool CEEInfo::checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, return result; } +static unsigned MarkGCField(BYTE* gcPtrs, CorInfoGCType type) +{ + STANDARD_VM_CONTRACT; + + // Ensure that if we have multiple fields with the same offset, + // that we don't double count the data in the gc layout. + if (*gcPtrs == TYPE_GC_NONE) + { + *gcPtrs = type; + return 1; + } + else if (*gcPtrs != type) + { + COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + } + + return 0; +} + /*********************************************************************/ static unsigned ComputeGCLayout(MethodTable * pMT, BYTE* gcPtrs) { STANDARD_VM_CONTRACT; - unsigned result = 0; - _ASSERTE(pMT->IsValueType()); if (pMT->HasSameTypeDefAs(g_pByReferenceClass)) - { - if (gcPtrs[0] == TYPE_GC_NONE) - { - gcPtrs[0] = TYPE_GC_BYREF; - result++; - } - else if (gcPtrs[0] != TYPE_GC_BYREF) - { - COMPlusThrowHR(COR_E_BADIMAGEFORMAT); - } - return result; - } + return MarkGCField(gcPtrs, TYPE_GC_BYREF); + unsigned result = 0; ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS); for (FieldDesc *pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next()) { int fieldStartIndex = pFD->GetOffset() / TARGET_POINTER_SIZE; - if (pFD->GetFieldType() != ELEMENT_TYPE_VALUETYPE) - { - if (pFD->IsObjRef()) - { - if (gcPtrs[fieldStartIndex] == TYPE_GC_NONE) - { - gcPtrs[fieldStartIndex] = TYPE_GC_REF; - result++; - } - else if (gcPtrs[fieldStartIndex] != TYPE_GC_REF) - { - COMPlusThrowHR(COR_E_BADIMAGEFORMAT); - } - } - } - else + if (pFD->GetFieldType() == ELEMENT_TYPE_VALUETYPE) { MethodTable * pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable(); result += ComputeGCLayout(pFieldMT, gcPtrs + fieldStartIndex); } + else if (pFD->IsObjRef()) + { + result += MarkGCField(gcPtrs + fieldStartIndex, TYPE_GC_REF); + } + else if (pFD->IsByRef()) + { + result += MarkGCField(gcPtrs + fieldStartIndex, TYPE_GC_BYREF); + } } return result; } @@ -7523,8 +7523,7 @@ bool containsStackCrawlMarkLocal(MethodDesc* ftn) *************************************************************/ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, - CORINFO_METHOD_HANDLE hCallee, - uint32_t* pRestrictions) + CORINFO_METHOD_HANDLE hCallee) { CONTRACTL { THROWS; @@ -7534,7 +7533,6 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, CorInfoInline result = INLINE_PASS; // By default we pass. // Do not set pass in the rest of the method. - DWORD dwRestrictions = 0; // By default, no restrictions const char * szFailReason = NULL; // for reportInlineDecision JIT_TO_EE_TRANSITION(); @@ -7609,23 +7607,6 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, } } - // - // Perform the Cross-Assembly inlining checks - // - { - Module * pCalleeModule = pCallee->GetModule(); - - // TODO: We can probably be smarter here if the caller is jitted, as we will - // know for sure if the inlinee has really no string interning active (currently - // it's only on in the ngen case (besides requiring the attribute)), but this is getting - // too subtle. Will only do if somebody screams about it, as bugs here are going to - // be tough to find - if ((pOrigCallerModule != pCalleeModule) && pCalleeModule->IsNoStringInterning()) - { - dwRestrictions |= INLINE_NO_CALLEE_LDSTR; - } - } - #ifdef PROFILING_SUPPORTED if (CORProfilerPresent()) { @@ -7699,28 +7680,6 @@ exit: ; EE_TO_JIT_TRANSITION(); - if (result == INLINE_PASS && dwRestrictions) - { - if (pRestrictions) - { - *pRestrictions = dwRestrictions; - } - else - { - // If the jitter didn't want to know about restrictions, it shouldn't be inlining - result = INLINE_FAIL; - szFailReason = "Inlinee has restrictions the JIT doesn't want"; - } - } - else - { - if (pRestrictions) - { - // Denied inlining, makes no sense to pass out restrictions, - *pRestrictions = 0; - } - } - if (dontInline(result)) { // If you hit this assert, it means you added a new way to prevent inlining @@ -13186,12 +13145,7 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, return TRUE; } - // For generic instantiations compiled into the ngen image of some other - // client assembly, we need to ensure that we intern the string - // in the defining assembly. - bool mayNeedToSyncWithFixups = pInfoModule != currentModule; - - result = (size_t) pInfoModule->ResolveStringRef(TokenFromRid(rid, mdtString), currentModule->GetDomain(), mayNeedToSyncWithFixups); + result = (size_t) pInfoModule->ResolveStringRef(TokenFromRid(rid, mdtString), currentModule->GetDomain()); } } break; diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 59566e2e717179..19a63dd9255443 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -3991,7 +3991,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, { Module * pTokenModule; dwByValueClassToken = fsig.GetArgProps().PeekValueTypeTokenClosed(GetModule(), &bmtGenerics->typeContext, &pTokenModule); - fIsByValue = TRUE; // By-value class BAD_FORMAT_NOTHROW_ASSERT(dwByValueClassToken != 0); @@ -4067,6 +4066,8 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList, // TypedReference shares the rest of the code here IS_VALUETYPE: { + fIsByValue = TRUE; + // It's not self-referential so try to load it if (pByValueClass == NULL) { @@ -8390,7 +8391,6 @@ MethodTableBuilder::HandleExplicitLayout( { STANDARD_VM_CONTRACT; - // Instance slice size is the total size of an instance, and is calculated as // the field whose offset and size add to the greatest number. UINT instanceSliceSize = 0; @@ -8425,13 +8425,13 @@ MethodTableBuilder::HandleExplicitLayout( pFieldLayout[i] = empty; } - // go through each field and look for invalid layout + // Go through each field and look for invalid layout. // (note that we are more permissive than what Ecma allows. We only disallow the minimum set necessary to // close security holes.) // - // This is what we implment: + // This is what we implement: // - // 1. Verify that every OREF is on a valid alignment + // 1. Verify that every OREF or BYREF is on a valid alignment. // 2. Verify that OREFs only overlap with other OREFs. // 3. If an OREF does overlap with another OREF, the class is marked unverifiable. // 4. If an overlap of any kind occurs, the class will be marked NotTightlyPacked (affects ValueType.Equals()). @@ -8444,7 +8444,6 @@ MethodTableBuilder::HandleExplicitLayout( isObject[i] = oref; } - ExplicitClassTrust explicitClassTrust; UINT valueClassCacheIndex = ((UINT)(-1)); @@ -8480,7 +8479,8 @@ MethodTableBuilder::HandleExplicitLayout( // "i" indexes all fields, valueClassCacheIndex indexes non-static fields only. Don't get them confused! valueClassCacheIndex++; - if (CorTypeInfo::IsObjRef(pFD->GetFieldType())) + CorElementType type = pFD->GetFieldType(); + if (CorTypeInfo::IsObjRef(type) || CorTypeInfo::IsByRef(type)) { // Check that the ref offset is pointer aligned if ((pFD->GetOffset_NoLogging() & ((ULONG)TARGET_POINTER_SIZE - 1)) != 0) @@ -8488,9 +8488,13 @@ MethodTableBuilder::HandleExplicitLayout( badOffset = pFD->GetOffset_NoLogging(); fieldTrust.SetTrust(ExplicitFieldTrust::kNone); - // If we got here, OREF field was not pointer aligned. THROW. + // If we got here, OREF or BYREF field was not pointer aligned. THROW. break; } + } + + if (CorTypeInfo::IsObjRef(type)) + { // check if overlaps another object if (memcmp((void *)&pFieldLayout[pFD->GetOffset_NoLogging()], (void *)isObject, sizeof(isObject)) == 0) { diff --git a/src/coreclr/vm/nativeimage.cpp b/src/coreclr/vm/nativeimage.cpp index 2664a44ad2d18b..37ed957032f303 100644 --- a/src/coreclr/vm/nativeimage.cpp +++ b/src/coreclr/vm/nativeimage.cpp @@ -123,7 +123,15 @@ NativeImage *NativeImage::Open( if (pExistingImage != nullptr) { *isNewNativeImage = false; - return pExistingImage->GetAssemblyBinder() == pAssemblyBinder ? pExistingImage : nullptr; + if (pExistingImage->GetAssemblyBinder() == pAssemblyBinder) + { + pExistingImage->AddComponentAssemblyToCache(componentModule->GetAssembly()); + return pExistingImage; + } + else + { + return nullptr; + } } SString path = componentModule->GetPath(); @@ -237,11 +245,33 @@ NativeImage *NativeImage::Open( // No pre-existing image, new image has been stored in the map *isNewNativeImage = true; amTracker.SuppressRelease(); + image->AddComponentAssemblyToCache(componentModule->GetAssembly()); return image.Extract(); } // Return pre-existing image if it was loaded into the same ALC, null otherwise *isNewNativeImage = false; - return (pExistingImage->GetAssemblyBinder() == pAssemblyBinder ? pExistingImage : nullptr); + if (pExistingImage->GetAssemblyBinder() == pAssemblyBinder) + { + pExistingImage->AddComponentAssemblyToCache(componentModule->GetAssembly()); + return pExistingImage; + } + else + { + return nullptr; + } +} +#endif + +#ifndef DACCESS_COMPILE +void NativeImage::AddComponentAssemblyToCache(Assembly *assembly) +{ + STANDARD_VM_CONTRACT; + + const AssemblyNameIndex *assemblyNameIndex = m_assemblySimpleNameToIndexMap.LookupPtr(assembly->GetSimpleName()); + if (assemblyNameIndex != nullptr) + { + VolatileStore(&m_pNativeMetadataAssemblyRefMap[assemblyNameIndex->Index], assembly); + } } #endif diff --git a/src/coreclr/vm/nativeimage.h b/src/coreclr/vm/nativeimage.h index 4774365197f2be..b9c1e8f6b81180 100644 --- a/src/coreclr/vm/nativeimage.h +++ b/src/coreclr/vm/nativeimage.h @@ -93,6 +93,7 @@ class NativeImage private: NativeImage(AssemblyBinder *pAssemblyBinder, PEImageLayout *peImageLayout, LPCUTF8 imageFileName); + void AddComponentAssemblyToCache(Assembly *assembly); protected: void Initialize(READYTORUN_HEADER *header, LoaderAllocator *loaderAllocator, AllocMemTracker *pamTracker); diff --git a/src/coreclr/vm/object.cpp b/src/coreclr/vm/object.cpp index 4a0ac960e9ace9..9cb54ede586a80 100644 --- a/src/coreclr/vm/object.cpp +++ b/src/coreclr/vm/object.cpp @@ -1917,6 +1917,13 @@ void ExceptionObject::SetStackTrace(I1ARRAYREF stackTrace, PTRARRAYREF dynamicMe } CONTRACTL_END; +#ifdef STRESS_LOG + if (StressLog::StressLogOn(~0u, 0)) + { + StressLog::CreateThreadStressLog(); + } +#endif + SpinLock::AcquireLock(&g_StackTraceArrayLock); SetObjectReference((OBJECTREF*)&_stackTrace, (OBJECTREF)stackTrace); diff --git a/src/coreclr/vm/object.inl b/src/coreclr/vm/object.inl index e61f2eb443babf..46b8db4d0d841f 100644 --- a/src/coreclr/vm/object.inl +++ b/src/coreclr/vm/object.inl @@ -272,38 +272,4 @@ inline TypeHandle Object::GetGCSafeTypeHandle() const return TypeHandle(pMT); } -template -inline void FindByRefPointerOffsetsInByRefLikeObject(PTR_MethodTable pMT, SIZE_T baseOffset, const F processPointerOffset) -{ - WRAPPER_NO_CONTRACT; - _ASSERTE(pMT != nullptr); - _ASSERTE(pMT->IsByRefLike()); - - if (pMT->HasSameTypeDefAs(g_pByReferenceClass)) - { - processPointerOffset(baseOffset); - return; - } - - ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS); - for (FieldDesc *pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next()) - { - if (pFD->GetFieldType() != ELEMENT_TYPE_VALUETYPE) - { - continue; - } - - // TODO: GetApproxFieldTypeHandleThrowing may throw. This is a potential stress problem for fragile NGen of non-CoreLib - // assemblies. It won't ever throw for CoreCLR with R2R. Figure out if anything needs to be done to deal with the - // exception. - PTR_MethodTable pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable(); - if (!pFieldMT->IsByRefLike()) - { - continue; - } - - FindByRefPointerOffsetsInByRefLikeObject(pFieldMT, baseOffset + pFD->GetOffset(), processPointerOffset); - } -} - #endif // _OBJECT_INL_ diff --git a/src/coreclr/vm/peassembly.h b/src/coreclr/vm/peassembly.h index 8cb12f986c8bb3..a051343f2e1fd9 100644 --- a/src/coreclr/vm/peassembly.h +++ b/src/coreclr/vm/peassembly.h @@ -44,7 +44,7 @@ class EditAndContinueModule; class PEAssembly; class SimpleRWLock; -typedef VPTR(PEAssembly) PTR_PEAssembly; +typedef DPTR(PEAssembly) PTR_PEAssembly; // -------------------------------------------------------------------------------- // Types diff --git a/src/coreclr/vm/siginfo.cpp b/src/coreclr/vm/siginfo.cpp index a197fbc87cabd9..5a277914d8cee5 100644 --- a/src/coreclr/vm/siginfo.cpp +++ b/src/coreclr/vm/siginfo.cpp @@ -4903,20 +4903,67 @@ void PromoteCarefully(promote_func fn, (*fn) (ppObj, sc, flags); } +class ByRefPointerOffsetsReporter +{ + promote_func* _fn; + ScanContext* _sc; + PTR_VOID _src; + + void Report(SIZE_T pointerOffset) + { + WRAPPER_NO_CONTRACT; + PTR_PTR_Object fieldRef = dac_cast(PTR_BYTE(_src) + pointerOffset); + (*_fn)(fieldRef, _sc, GC_CALL_INTERIOR); + } + +public: + ByRefPointerOffsetsReporter(promote_func* fn, ScanContext* sc, PTR_VOID pSrc) + : _fn{fn} + , _sc{sc} + , _src{pSrc} + { + WRAPPER_NO_CONTRACT; + } + + void Find(PTR_MethodTable pMT, SIZE_T baseOffset) + { + WRAPPER_NO_CONTRACT; + _ASSERTE(pMT != nullptr); + _ASSERTE(pMT->IsByRefLike()); + + if (pMT->HasSameTypeDefAs(g_pByReferenceClass)) + { + Report(baseOffset); + return; + } + + ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS); + for (FieldDesc* pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next()) + { + if (pFD->GetFieldType() == ELEMENT_TYPE_VALUETYPE) + { + PTR_MethodTable pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable(); + if (pFieldMT->IsByRefLike()) + { + Find(pFieldMT, baseOffset + pFD->GetOffset()); + } + } + else if (pFD->IsByRef()) + { + Report(baseOffset + pFD->GetOffset()); + } + } + } +}; + void ReportPointersFromValueType(promote_func *fn, ScanContext *sc, PTR_MethodTable pMT, PTR_VOID pSrc) { WRAPPER_NO_CONTRACT; if (pMT->IsByRefLike()) { - FindByRefPointerOffsetsInByRefLikeObject( - pMT, - 0 /* baseOffset */, - [&](SIZE_T pointerOffset) - { - PTR_PTR_Object fieldRef = dac_cast(PTR_BYTE(pSrc) + pointerOffset); - (*fn)(fieldRef, sc, GC_CALL_INTERIOR); - }); + ByRefPointerOffsetsReporter reporter{fn, sc, pSrc}; + reporter.Find(pMT, 0 /* baseOffset */); } if (!pMT->ContainsPointers()) diff --git a/src/coreclr/vm/spinlock.cpp b/src/coreclr/vm/spinlock.cpp index c9173198f620fa..70ad06459777f9 100644 --- a/src/coreclr/vm/spinlock.cpp +++ b/src/coreclr/vm/spinlock.cpp @@ -283,6 +283,7 @@ void SpinLock::dbg_PreEnterLock() // SpinLock can not be nested. _ASSERTE ((pThread->m_StateNC & Thread::TSNC_OwnsSpinLock) == 0); + IncCantAllocCount(); pThread->SetThreadStateNC(Thread::TSNC_OwnsSpinLock); if (!pThread->PreemptiveGCDisabled()) @@ -321,6 +322,7 @@ void SpinLock::dbg_LeaveLock() if (pThread) { _ASSERTE ((pThread->m_StateNC & Thread::TSNC_OwnsSpinLock) != 0); + DecCantAllocCount(); pThread->ResetThreadStateNC(Thread::TSNC_OwnsSpinLock); INCONTRACT(pThread->EndNoTriggerGC()); } diff --git a/src/coreclr/vm/zapsig.cpp b/src/coreclr/vm/zapsig.cpp index b66c7b10571384..6dede7725e291a 100644 --- a/src/coreclr/vm/zapsig.cpp +++ b/src/coreclr/vm/zapsig.cpp @@ -654,31 +654,35 @@ Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule, else { index -= assemblyRefMax; - tkAssemblyRef = RidToToken(index, mdtAssemblyRef); - IMDInternalImport * pMDImportOverride = (nativeImage != NULL - ? nativeImage->GetManifestMetadata() : fromModule->GetNativeAssemblyImport(FALSE)); - if (pMDImportOverride != NULL) + pAssembly = fromModule->GetNativeMetadataAssemblyRefFromCache(index); + if (pAssembly == NULL) { - BOOL fValidAssemblyRef = TRUE; - LPCSTR pAssemblyName; - DWORD dwFlags; - if (FAILED(pMDImportOverride->GetAssemblyRefProps(tkAssemblyRef, - NULL, - NULL, - &pAssemblyName, - NULL, - NULL, - NULL, - &dwFlags))) - { // Unexpected failure reading MetaData - fValidAssemblyRef = FALSE; - } - - if (fValidAssemblyRef) + tkAssemblyRef = RidToToken(index, mdtAssemblyRef); + IMDInternalImport * pMDImportOverride = (nativeImage != NULL + ? nativeImage->GetManifestMetadata() : fromModule->GetNativeAssemblyImport(FALSE)); + if (pMDImportOverride != NULL) { - pAssembly = fromModule->GetAssemblyIfLoaded( - tkAssemblyRef, - pMDImportOverride); + BOOL fValidAssemblyRef = TRUE; + LPCSTR pAssemblyName; + DWORD dwFlags; + if (FAILED(pMDImportOverride->GetAssemblyRefProps(tkAssemblyRef, + NULL, + NULL, + &pAssemblyName, + NULL, + NULL, + NULL, + &dwFlags))) + { // Unexpected failure reading MetaData + fValidAssemblyRef = FALSE; + } + + if (fValidAssemblyRef) + { + pAssembly = fromModule->GetAssemblyIfLoaded( + tkAssemblyRef, + pMDImportOverride); + } } } } diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props index f122fd1fcf526d..e94c73bb92386f 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -235,6 +235,7 @@ + diff --git a/src/libraries/Common/src/Internal/Cryptography/AsymmetricAlgorithmHelpers.Der.cs b/src/libraries/Common/src/Internal/Cryptography/AsymmetricAlgorithmHelpers.Der.cs index b750a2de5e9d8f..d3c442760423c4 100644 --- a/src/libraries/Common/src/Internal/Cryptography/AsymmetricAlgorithmHelpers.Der.cs +++ b/src/libraries/Common/src/Internal/Cryptography/AsymmetricAlgorithmHelpers.Der.cs @@ -143,7 +143,6 @@ static int GetDerLengthLength(int payloadLength) } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS /// /// Converts IeeeP1363 format to the specified signature format /// @@ -182,7 +181,6 @@ internal static byte[] ConvertSignatureToIeeeP1363( currentFormat.ToString()); } } -#endif public static int BitsToBytes(int bitLength) { @@ -214,7 +212,6 @@ private static void CopySignatureField(ReadOnlySpan signatureField, Span signatureField, Span true; #endif + [UnsupportedOSPlatformGuard("browser")] + internal static bool HasMD5 { get; } = +#if NET5_0_OR_GREATER + !OperatingSystem.IsBrowser(); +#else + true; +#endif + [return: NotNullIfNotNull("src")] public static byte[]? CloneByteArray(this byte[]? src) { diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs index 39c980bdfab125..8de978aea5df30 100644 --- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs +++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Cipher.cs @@ -64,7 +64,15 @@ internal static void CipherSetNonceLength(SafeEvpCipherCtxHandle ctx, int nonceL [GeneratedDllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_CipherReset")] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvpCipherReset(SafeEvpCipherCtxHandle ctx); + private static unsafe partial bool EvpCipherReset(SafeEvpCipherCtxHandle ctx, byte* pIv, int cIv); + + internal static unsafe bool EvpCipherReset(SafeEvpCipherCtxHandle ctx, ReadOnlySpan iv) + { + fixed (byte* pIv = &MemoryMarshal.GetReference(iv)) + { + return EvpCipherReset(ctx, pIv, iv.Length); + } + } [GeneratedDllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_CipherCtxSetPadding")] [return: MarshalAs(UnmanagedType.Bool)] diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.Cipher.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.Cipher.cs index 68d18a56983d41..b9496982622504 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.Cipher.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.Cipher.cs @@ -76,7 +76,15 @@ internal static void EvpCipherSetCcmNonceLength(SafeEvpCipherCtxHandle ctx, int [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpCipherReset")] [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool EvpCipherReset(SafeEvpCipherCtxHandle ctx); + private static unsafe partial bool EvpCipherReset(SafeEvpCipherCtxHandle ctx, byte* pIv, int cIv); + + internal static unsafe bool EvpCipherReset(SafeEvpCipherCtxHandle ctx, ReadOnlySpan iv) + { + fixed (byte* pIv = &MemoryMarshal.GetReference(iv)) + { + return EvpCipherReset(ctx, pIv, iv.Length); + } + } [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpCipherCtxSetPadding")] [return: MarshalAs(UnmanagedType.Bool)] diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 12b75443f74723..22e7d9bd1e2b62 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -356,13 +356,12 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia internal static SecurityStatusPal SslRenegotiate(SafeSslHandle sslContext, out byte[]? outputBuffer) { - int ret = Interop.Ssl.SslRenegotiate(sslContext); + int ret = Interop.Ssl.SslRenegotiate(sslContext, out Ssl.SslErrorCode errorCode); outputBuffer = Array.Empty(); if (ret != 1) { - GetSslError(sslContext, ret, out Exception? exception); - return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exception); + return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, GetSslError(ret, errorCode)); } return new SecurityStatusPal(SecurityStatusPalErrorCode.OK); } @@ -382,23 +381,21 @@ internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, } } - int retVal = Ssl.SslDoHandshake(context); + int retVal = Ssl.SslDoHandshake(context, out Ssl.SslErrorCode errorCode); if (retVal != 1) { - Exception? innerError; - Ssl.SslErrorCode error = GetSslError(context, retVal, out innerError); - - if (error == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) + if (errorCode == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) { return SecurityStatusPalErrorCode.CredentialsNeeded; } - if ((retVal != -1) || (error != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) + if ((retVal != -1) || (errorCode != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) { + Exception? innerError = GetSslError(retVal, errorCode); + // Handshake failed, but even if the handshake does not need to read, there may be an Alert going out. // To handle that we will fall-through the block below to pull it out, and we will fail after. - handshakeException = new SslException(SR.Format(SR.net_ssl_handshake_failed_error, error), innerError); - Crypto.ErrClearError(); + handshakeException = new SslException(SR.Format(SR.net_ssl_handshake_failed_error, errorCode), innerError); } } @@ -447,17 +444,7 @@ internal static int Encrypt(SafeSslHandle context, ReadOnlySpan input, ref ulong assertNoError = Crypto.ErrPeekError(); Debug.Assert(assertNoError == 0, $"OpenSsl error queue is not empty, run: 'openssl errstr {assertNoError:X}' for original error."); #endif - errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE; - - int retVal; - Exception? innerError = null; - - retVal = Ssl.SslWrite(context, ref MemoryMarshal.GetReference(input), input.Length); - - if (retVal != input.Length) - { - errorCode = GetSslError(context, retVal, out innerError); - } + int retVal = Ssl.SslWrite(context, ref MemoryMarshal.GetReference(input), input.Length, out errorCode); if (retVal != input.Length) { @@ -471,7 +458,7 @@ internal static int Encrypt(SafeSslHandle context, ReadOnlySpan input, ref break; default: - throw new SslException(SR.Format(SR.net_ssl_encrypt_failed, errorCode), innerError); + throw new SslException(SR.Format(SR.net_ssl_encrypt_failed, errorCode), GetSslError(retVal, errorCode)); } } else @@ -501,17 +488,14 @@ internal static int Decrypt(SafeSslHandle context, Span buffer, out Ssl.Ss ulong assertNoError = Crypto.ErrPeekError(); Debug.Assert(assertNoError == 0, $"OpenSsl error queue is not empty, run: 'openssl errstr {assertNoError:X}' for original error."); #endif - errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE; - BioWrite(context.InputBio!, buffer); - int retVal = Ssl.SslRead(context, ref MemoryMarshal.GetReference(buffer), buffer.Length); + int retVal = Ssl.SslRead(context, ref MemoryMarshal.GetReference(buffer), buffer.Length, out errorCode); if (retVal > 0) { return retVal; } - errorCode = GetSslError(context, retVal, out Exception? innerError); switch (errorCode) { // indicate end-of-file @@ -526,7 +510,7 @@ internal static int Decrypt(SafeSslHandle context, Span buffer, out Ssl.Ss break; default: - throw new SslException(SR.Format(SR.net_ssl_decrypt_failed, errorCode), innerError); + throw new SslException(SR.Format(SR.net_ssl_decrypt_failed, errorCode), GetSslError(retVal, errorCode)); } return 0; @@ -647,14 +631,13 @@ private static void BioWrite(SafeBioHandle bio, ReadOnlySpan buffer) } } - private static Ssl.SslErrorCode GetSslError(SafeSslHandle context, int result, out Exception? innerError) + private static Exception? GetSslError(int result, Ssl.SslErrorCode retVal) { - ErrorInfo lastErrno = Sys.GetLastErrorInfo(); // cache it before we make more P/Invoke calls, just in case we need it - - Ssl.SslErrorCode retVal = Ssl.SslGetError(context, result); + Exception? innerError; switch (retVal) { case Ssl.SslErrorCode.SSL_ERROR_SYSCALL: + ErrorInfo lastErrno = Sys.GetLastErrorInfo(); // Some I/O error occurred innerError = Crypto.ErrPeekError() != 0 ? Crypto.CreateOpenSslCryptographicException() : // crypto error queue not empty @@ -673,7 +656,8 @@ private static Ssl.SslErrorCode GetSslError(SafeSslHandle context, int result, o innerError = null; break; } - return retVal; + + return innerError; } private static void SetSslCertificate(SafeSslContextHandle contextPtr, SafeX509Handle certPtr, SafeEvpPKeyHandle keyPtr) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs index 379ab7586ed38c..6ccb1307886f71 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs @@ -75,13 +75,13 @@ internal static partial class Ssl } [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslWrite", SetLastError = true)] - internal static partial int SslWrite(SafeSslHandle ssl, ref byte buf, int num); + internal static partial int SslWrite(SafeSslHandle ssl, ref byte buf, int num, out SslErrorCode error); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslRead", SetLastError = true)] - internal static partial int SslRead(SafeSslHandle ssl, ref byte buf, int num); + internal static partial int SslRead(SafeSslHandle ssl, ref byte buf, int num, out SslErrorCode error); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslRenegotiate")] - internal static partial int SslRenegotiate(SafeSslHandle ssl); + internal static partial int SslRenegotiate(SafeSslHandle ssl, out SslErrorCode error); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_IsSslRenegotiatePending")] [return: MarshalAs(UnmanagedType.Bool)] @@ -97,7 +97,7 @@ internal static partial class Ssl internal static partial void SslSetBio(SafeSslHandle ssl, SafeBioHandle rbio, SafeBioHandle wbio); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslDoHandshake", SetLastError = true)] - internal static partial int SslDoHandshake(SafeSslHandle ssl); + internal static partial int SslDoHandshake(SafeSslHandle ssl, out SslErrorCode error); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_IsSslStateOK")] [return: MarshalAs(UnmanagedType.Bool)] diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptCreateHash.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptCreateHash.cs index 0a60ee7918ac3c..b57a4b0f619273 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptCreateHash.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptCreateHash.cs @@ -19,7 +19,7 @@ internal enum CryptCreateHashFlags : int internal static partial bool CryptCreateHash( SafeProvHandle hProv, int Algid, - SafeKeyHandle hKey, + SafeCapiKeyHandle hKey, CryptCreateHashFlags dwFlags, out SafeHashHandle phHash); } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDecrypt.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDecrypt.cs index 7865c1180ff8ff..3f05d5c223e7c6 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDecrypt.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDecrypt.cs @@ -16,7 +16,7 @@ internal enum CryptDecryptFlags : int [GeneratedDllImport(Libraries.Advapi32, SetLastError = true)] public static partial bool CryptDecrypt( - SafeKeyHandle hKey, + SafeCapiKeyHandle hKey, SafeHashHandle hHash, bool Final, int dwFlags, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDeriveKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDeriveKey.cs index 2bc7d4ed8d8ba7..51b77aef3d0ac5 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDeriveKey.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDeriveKey.cs @@ -14,6 +14,6 @@ internal static partial bool CryptDeriveKey( int Algid, SafeHashHandle hBaseData, int dwFlags, - out SafeKeyHandle phKey); + out SafeCapiKeyHandle phKey); } } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptEncrypt.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptEncrypt.cs index fa883e5eef421d..17e50c1e59d0fd 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptEncrypt.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptEncrypt.cs @@ -10,7 +10,7 @@ internal static partial class Advapi32 { [GeneratedDllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, SetLastError = true)] public static partial bool CryptEncrypt( - SafeKeyHandle hKey, + SafeCapiKeyHandle hKey, SafeHashHandle hHash, bool Final, int dwFlags, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptExportKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptExportKey.cs index 9eb16f40190356..633997f99880ee 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptExportKey.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptExportKey.cs @@ -10,8 +10,8 @@ internal static partial class Advapi32 { [GeneratedDllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, SetLastError = true)] public static partial bool CryptExportKey( - SafeKeyHandle hKey, - SafeKeyHandle hExpKey, + SafeCapiKeyHandle hKey, + SafeCapiKeyHandle hExpKey, int dwBlobType, int dwFlags, byte[]? pbData, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGenKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGenKey.cs index d19c090d84d604..cf6aaf36b1c151 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGenKey.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGenKey.cs @@ -9,6 +9,6 @@ internal static partial class Interop internal static partial class Advapi32 { [GeneratedDllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, SetLastError = true)] - internal static partial bool CryptGenKey(SafeProvHandle hProv, int Algid, int dwFlags, out SafeKeyHandle phKey); + internal static partial bool CryptGenKey(SafeProvHandle hProv, int Algid, int dwFlags, out SafeCapiKeyHandle phKey); } } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetKeyParam.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetKeyParam.cs index 9737c2b0663886..63f33ffa392275 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetKeyParam.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetKeyParam.cs @@ -19,7 +19,7 @@ internal enum CryptGetKeyParamFlags : int [GeneratedDllImport(Libraries.Advapi32, SetLastError = true)] public static partial bool CryptGetKeyParam( - SafeKeyHandle hKey, + SafeCapiKeyHandle hKey, CryptGetKeyParamFlags dwParam, byte[]? pbData, ref int pdwDataLen, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetUserKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetUserKey.cs index c5080a00784701..88b5d00e563892 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetUserKey.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetUserKey.cs @@ -9,6 +9,6 @@ internal static partial class Interop internal static partial class Advapi32 { [GeneratedDllImport(Libraries.Advapi32, SetLastError = true)] - internal static partial bool CryptGetUserKey(SafeProvHandle hProv, int dwKeySpec, out SafeKeyHandle phUserKey); + internal static partial bool CryptGetUserKey(SafeProvHandle hProv, int dwKeySpec, out SafeCapiKeyHandle phUserKey); } } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptImportKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptImportKey.cs index f5e73879d99ca3..3c8cb90d99f5c8 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptImportKey.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptImportKey.cs @@ -13,8 +13,8 @@ internal static unsafe partial bool CryptImportKey( SafeProvHandle hProv, byte* pbData, int dwDataLen, - SafeKeyHandle hPubKey, + SafeCapiKeyHandle hPubKey, int dwFlags, - out SafeKeyHandle phKey); + out SafeCapiKeyHandle phKey); } } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSetKeyParam.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSetKeyParam.cs index 5fb1c83ff37e51..07d510705e2f73 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSetKeyParam.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSetKeyParam.cs @@ -9,9 +9,9 @@ internal static partial class Interop internal static partial class Advapi32 { [GeneratedDllImport(Libraries.Advapi32, SetLastError = true)] - public static partial bool CryptSetKeyParam(SafeKeyHandle hKey, int dwParam, byte[] pbData, int dwFlags); + public static partial bool CryptSetKeyParam(SafeCapiKeyHandle hKey, int dwParam, byte[] pbData, int dwFlags); [GeneratedDllImport(Libraries.Advapi32, SetLastError = true)] - public static partial bool CryptSetKeyParam(SafeKeyHandle safeKeyHandle, int dwParam, ref int pdw, int dwFlags); + public static partial bool CryptSetKeyParam(SafeCapiKeyHandle safeKeyHandle, int dwParam, ref int pdw, int dwFlags); } } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSignHash.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSignHash.cs index 0d9f3a17031410..dd7a12c30b397e 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSignHash.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSignHash.cs @@ -38,7 +38,7 @@ public static partial bool CryptVerifySignature( SafeHashHandle hHash, byte[] pbSignature, int dwSigLen, - SafeKeyHandle hPubKey, + SafeCapiKeyHandle hPubKey, string? szDescription, CryptSignAndVerifyHashFlags dwFlags); } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/SafeKeyHandle.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/SafeKeyHandle.cs index 5f12dd16db064a..b8a0e5c944b20f 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/SafeKeyHandle.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/SafeKeyHandle.cs @@ -16,13 +16,13 @@ namespace System.Security.Cryptography /// of the key handle and provider handle. This also applies to hash handles, which point to a /// CRYPT_HASH_CTX. Those structures are defined in COMCryptography.h /// - internal sealed class SafeKeyHandle : SafeHandleZeroOrMinusOneIsInvalid + internal sealed class SafeCapiKeyHandle : SafeHandleZeroOrMinusOneIsInvalid { private int _keySpec; private bool _fPublicOnly; private SafeProvHandle? _parent; - public SafeKeyHandle() : base(true) + public SafeCapiKeyHandle() : base(true) { SetHandle(IntPtr.Zero); _keySpec = 0; @@ -70,14 +70,14 @@ internal void SetParent(SafeProvHandle parent) _parent.DangerousAddRef(ref ignored); } - internal static SafeKeyHandle InvalidHandle + internal static SafeCapiKeyHandle InvalidHandle { - get { return SafeHandleCache.GetInvalidHandle(() => new SafeKeyHandle()); } + get { return SafeHandleCache.GetInvalidHandle(() => new SafeCapiKeyHandle()); } } protected override void Dispose(bool disposing) { - if (!SafeHandleCache.IsCachedInvalidHandle(this)) + if (!SafeHandleCache.IsCachedInvalidHandle(this)) { base.Dispose(disposing); } diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptImportKey.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptImportKey.cs index 13d709643a1846..94e650df6362ae 100644 --- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptImportKey.cs +++ b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptImportKey.cs @@ -16,28 +16,42 @@ internal static unsafe SafeKeyHandle BCryptImportKey(SafeAlgorithmHandle hAlg, R const string BCRYPT_KEY_DATA_BLOB = "KeyDataBlob"; int keySize = key.Length; int blobSize = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + keySize; - byte[] blob = new byte[blobSize]; + + // 64 is large enough to hold a BCRYPT_KEY_DATA_BLOB_HEADER and an AES-256 key with room to spare. + int MaxStackKeyBlob = 64; + Span blob = stackalloc byte[MaxStackKeyBlob]; + + if (blobSize > MaxStackKeyBlob) + { + blob = new byte[blobSize]; + } + else + { + blob.Clear(); + } + fixed (byte* pbBlob = blob) { BCRYPT_KEY_DATA_BLOB_HEADER* pBlob = (BCRYPT_KEY_DATA_BLOB_HEADER*)pbBlob; pBlob->dwMagic = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_MAGIC; pBlob->dwVersion = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_VERSION1; pBlob->cbKeyData = (uint)keySize; - } - key.CopyTo(blob.AsSpan(sizeof(BCRYPT_KEY_DATA_BLOB_HEADER))); - SafeKeyHandle hKey; - NTSTATUS ntStatus = BCryptImportKey(hAlg, IntPtr.Zero, BCRYPT_KEY_DATA_BLOB, out hKey, IntPtr.Zero, 0, blob, blobSize, 0); - if (ntStatus != NTSTATUS.STATUS_SUCCESS) - { - throw CreateCryptographicException(ntStatus); - } - return hKey; + key.CopyTo(blob.Slice(sizeof(BCRYPT_KEY_DATA_BLOB_HEADER))); + SafeKeyHandle hKey; + NTSTATUS ntStatus = BCryptImportKey(hAlg, IntPtr.Zero, BCRYPT_KEY_DATA_BLOB, out hKey, IntPtr.Zero, 0, pbBlob, blobSize, 0); + if (ntStatus != NTSTATUS.STATUS_SUCCESS) + { + throw CreateCryptographicException(ntStatus); + } + + return hKey; + } } [StructLayout(LayoutKind.Sequential)] - private struct BCRYPT_KEY_DATA_BLOB_HEADER + internal struct BCRYPT_KEY_DATA_BLOB_HEADER { public uint dwMagic; public uint dwVersion; @@ -48,6 +62,6 @@ private struct BCRYPT_KEY_DATA_BLOB_HEADER } [GeneratedDllImport(Libraries.BCrypt, CharSet = CharSet.Unicode)] - private static partial NTSTATUS BCryptImportKey(SafeAlgorithmHandle hAlgorithm, IntPtr hImportKey, string pszBlobType, out SafeKeyHandle hKey, IntPtr pbKeyObject, int cbKeyObject, byte[] pbInput, int cbInput, int dwFlags); + private static unsafe partial NTSTATUS BCryptImportKey(SafeAlgorithmHandle hAlgorithm, IntPtr hImportKey, string pszBlobType, out SafeKeyHandle hKey, IntPtr pbKeyObject, int cbKeyObject, byte* pbInput, int cbInput, int dwFlags); } } diff --git a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Keys.cs b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Keys.cs index 406e0177f8ecfb..5d9fbe7595ed0a 100644 --- a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Keys.cs +++ b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Keys.cs @@ -11,8 +11,11 @@ internal static partial class Interop { internal static partial class NCrypt { + internal const string NCRYPT_CIPHER_KEY_BLOB = "CipherKeyBlob"; internal const string NCRYPT_PKCS8_PRIVATE_KEY_BLOB = "PKCS8_PRIVATEKEY"; + internal const int NCRYPT_CIPHER_KEY_BLOB_MAGIC = 0x52485043; //'CPHR' + [GeneratedDllImport(Interop.Libraries.NCrypt, CharSet = CharSet.Unicode)] internal static partial ErrorCode NCryptOpenKey(SafeNCryptProviderHandle hProvider, out SafeNCryptKeyHandle phKey, string pszKeyName, int dwLegacyKeySpec, CngKeyOpenOptions dwFlags); diff --git a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs index 20f987f6cc0530..54d6284d601c93 100644 --- a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs +++ b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography.Pal; +using System.Security.Cryptography.X509Certificates; namespace Microsoft.Win32.SafeHandles { diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs index a16f66c40c89eb..67e9d869a68dbd 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs @@ -34,6 +34,18 @@ internal Asn1Tag PeekTag() return Asn1Tag.Decode(_span, out _); } + internal ReadOnlySpan PeekContentBytes() + { + AsnDecoder.ReadEncodedValue( + _span, + _ruleSet, + out int contentOffset, + out int contentLength, + out _); + + return _span.Slice(contentOffset, contentLength); + } + internal ReadOnlySpan PeekEncodedValue() { AsnDecoder.ReadEncodedValue(_span, _ruleSet, out _, out _, out int consumed); diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs b/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs index b5e8c50c42b51e..f9ec1cb44be8eb 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs @@ -11,432 +11,425 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class DSAImplementation + public sealed partial class DSACng : DSA { -#endif - public sealed partial class DSACng : DSA - { - // For keysizes up to and including 1024 bits, CNG's blob format is BCRYPT_DSA_KEY_BLOB. - // For keysizes exceeding 1024 bits, CNG's blob format is BCRYPT_DSA_KEY_BLOB_V2. - private const int MaxV1KeySize = 1024; - - private const int Sha1HashOutputSize = 20; - private const int Sha256HashOutputSize = 32; - private const int Sha512HashOutputSize = 64; + // For keysizes up to and including 1024 bits, CNG's blob format is BCRYPT_DSA_KEY_BLOB. + // For keysizes exceeding 1024 bits, CNG's blob format is BCRYPT_DSA_KEY_BLOB_V2. + private const int MaxV1KeySize = 1024; - public override void ImportParameters(DSAParameters parameters) - { - if (parameters.P == null || parameters.Q == null || parameters.G == null || parameters.Y == null) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MissingFields); + private const int Sha1HashOutputSize = 20; + private const int Sha256HashOutputSize = 32; + private const int Sha512HashOutputSize = 64; - // J is not required and is not even used on CNG blobs. It should however be less than P (J == (P-1) / Q). This validation check - // is just to maintain parity with DSACryptoServiceProvider, which also performs this check. - if (parameters.J != null && parameters.J.Length >= parameters.P.Length) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPJ); + public override void ImportParameters(DSAParameters parameters) + { + if (parameters.P == null || parameters.Q == null || parameters.G == null || parameters.Y == null) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MissingFields); - bool hasPrivateKey = parameters.X != null; + // J is not required and is not even used on CNG blobs. It should however be less than P (J == (P-1) / Q). This validation check + // is just to maintain parity with DSACryptoServiceProvider, which also performs this check. + if (parameters.J != null && parameters.J.Length >= parameters.P.Length) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPJ); - int keySizeInBytes = parameters.P.Length; - int keySizeInBits = keySizeInBytes * 8; + bool hasPrivateKey = parameters.X != null; - if (parameters.G.Length != keySizeInBytes || parameters.Y.Length != keySizeInBytes) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPGY); + int keySizeInBytes = parameters.P.Length; + int keySizeInBits = keySizeInBytes * 8; - if (hasPrivateKey && parameters.X!.Length != parameters.Q.Length) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX); + if (parameters.G.Length != keySizeInBytes || parameters.Y.Length != keySizeInBytes) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPGY); - byte[] blob; - if (keySizeInBits <= MaxV1KeySize) - { - GenerateV1DsaBlob(out blob, parameters, keySizeInBytes, hasPrivateKey); - } - else - { - GenerateV2DsaBlob(out blob, parameters, keySizeInBytes, hasPrivateKey); - } + if (hasPrivateKey && parameters.X!.Length != parameters.Q.Length) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX); - ImportKeyBlob(blob, hasPrivateKey); + byte[] blob; + if (keySizeInBits <= MaxV1KeySize) + { + GenerateV1DsaBlob(out blob, parameters, keySizeInBytes, hasPrivateKey); } - - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - ReadOnlySpan source, - out int bytesRead) + else { - ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + GenerateV2DsaBlob(out blob, parameters, keySizeInBytes, hasPrivateKey); } - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - ReadOnlySpan source, - out int bytesRead) + ImportKeyBlob(blob, hasPrivateKey); + } + + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + } + + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + } + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters) + { + if (pbeParameters == null) + throw new ArgumentNullException(nameof(pbeParameters)); + + return CngPkcs8.ExportEncryptedPkcs8PrivateKey( + this, + passwordBytes, + pbeParameters); + } + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters) + { + if (pbeParameters == null) { - ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + throw new ArgumentNullException(nameof(pbeParameters)); } - public override byte[] ExportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - PbeParameters pbeParameters) - { - if (pbeParameters == null) - throw new ArgumentNullException(nameof(pbeParameters)); + PasswordBasedEncryption.ValidatePbeParameters( + pbeParameters, + password, + ReadOnlySpan.Empty); - return CngPkcs8.ExportEncryptedPkcs8PrivateKey( - this, - passwordBytes, - pbeParameters); + if (CngPkcs8.IsPlatformScheme(pbeParameters)) + { + return ExportEncryptedPkcs8(password, pbeParameters.IterationCount); } - public override byte[] ExportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - PbeParameters pbeParameters) - { - if (pbeParameters == null) - { - throw new ArgumentNullException(nameof(pbeParameters)); - } + return CngPkcs8.ExportEncryptedPkcs8PrivateKey( + this, + password, + pbeParameters); + } - PasswordBasedEncryption.ValidatePbeParameters( - pbeParameters, - password, - ReadOnlySpan.Empty); + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) + { + if (pbeParameters == null) + throw new ArgumentNullException(nameof(pbeParameters)); + + PasswordBasedEncryption.ValidatePbeParameters( + pbeParameters, + ReadOnlySpan.Empty, + passwordBytes); + + return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( + this, + passwordBytes, + pbeParameters, + destination, + out bytesWritten); + } - if (CngPkcs8.IsPlatformScheme(pbeParameters)) - { - return ExportEncryptedPkcs8(password, pbeParameters.IterationCount); - } + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) + { + if (pbeParameters == null) + throw new ArgumentNullException(nameof(pbeParameters)); - return CngPkcs8.ExportEncryptedPkcs8PrivateKey( - this, - password, - pbeParameters); - } + PasswordBasedEncryption.ValidatePbeParameters( + pbeParameters, + password, + ReadOnlySpan.Empty); - public override bool TryExportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - PbeParameters pbeParameters, - Span destination, - out int bytesWritten) + if (CngPkcs8.IsPlatformScheme(pbeParameters)) { - if (pbeParameters == null) - throw new ArgumentNullException(nameof(pbeParameters)); - - PasswordBasedEncryption.ValidatePbeParameters( - pbeParameters, - ReadOnlySpan.Empty, - passwordBytes); - - return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( - this, - passwordBytes, - pbeParameters, + return TryExportEncryptedPkcs8( + password, + pbeParameters.IterationCount, destination, out bytesWritten); } - public override bool TryExportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - PbeParameters pbeParameters, - Span destination, - out int bytesWritten) + return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( + this, + password, + pbeParameters, + destination, + out bytesWritten); + } + + private static unsafe void GenerateV1DsaBlob(out byte[] blob, DSAParameters parameters, int cbKey, bool includePrivate) + { + // We need to build a key blob structured as follows: + // + // BCRYPT_DSA_KEY_BLOB header + // byte[cbKey] P + // byte[cbKey] G + // byte[cbKey] Y + // -- Private only -- + // byte[Sha1HashOutputSize] X + + int blobSize = + sizeof(BCRYPT_DSA_KEY_BLOB) + + cbKey + + cbKey + + cbKey; + + if (includePrivate) + { + blobSize += Sha1HashOutputSize; + } + + blob = new byte[blobSize]; + fixed (byte* pDsaBlob = &blob[0]) { - if (pbeParameters == null) - throw new ArgumentNullException(nameof(pbeParameters)); + // Build the header + BCRYPT_DSA_KEY_BLOB* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB*)pDsaBlob; - PasswordBasedEncryption.ValidatePbeParameters( - pbeParameters, - password, - ReadOnlySpan.Empty); + pBcryptBlob->Magic = includePrivate ? KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC : KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC; + pBcryptBlob->cbKey = cbKey; - if (CngPkcs8.IsPlatformScheme(pbeParameters)) + int offset = sizeof(KeyBlobMagicNumber) + sizeof(int); // skip Magic and cbKey + + if (parameters.Seed != null) { - return TryExportEncryptedPkcs8( - password, - pbeParameters.IterationCount, - destination, - out bytesWritten); + // The Seed length is hardcoded into BCRYPT_DSA_KEY_BLOB, so check it now we can give a nicer error message. + if (parameters.Seed.Length != Sha1HashOutputSize) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_SeedRestriction_ShortKey); + + Interop.BCrypt.EmitBigEndian(blob, ref offset, parameters.Counter); + Interop.BCrypt.Emit(blob, ref offset, parameters.Seed); + } + else + { + // If Seed is not present, back fill both counter and seed with 0xff. Do not use parameters.Counter as CNG is more strict than CAPI and will reject + // anything other than 0xffffffff. That could complicate efforts to switch usage of DSACryptoServiceProvider to DSACng. + Interop.BCrypt.EmitByte(blob, ref offset, 0xff, Sha1HashOutputSize + sizeof(int)); } - return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( - this, - password, - pbeParameters, - destination, - out bytesWritten); - } + // The Q length is hardcoded into BCRYPT_DSA_KEY_BLOB, so check it now we can give a nicer error message. + if (parameters.Q!.Length != Sha1HashOutputSize) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_QRestriction_ShortKey); - private static unsafe void GenerateV1DsaBlob(out byte[] blob, DSAParameters parameters, int cbKey, bool includePrivate) - { - // We need to build a key blob structured as follows: - // - // BCRYPT_DSA_KEY_BLOB header - // byte[cbKey] P - // byte[cbKey] G - // byte[cbKey] Y - // -- Private only -- - // byte[Sha1HashOutputSize] X - - int blobSize = - sizeof(BCRYPT_DSA_KEY_BLOB) + - cbKey + - cbKey + - cbKey; + Interop.BCrypt.Emit(blob, ref offset, parameters.Q); + + Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB)}"); + Interop.BCrypt.Emit(blob, ref offset, parameters.P!); + Interop.BCrypt.Emit(blob, ref offset, parameters.G!); + Interop.BCrypt.Emit(blob, ref offset, parameters.Y!); if (includePrivate) { - blobSize += Sha1HashOutputSize; + Interop.BCrypt.Emit(blob, ref offset, parameters.X!); } - blob = new byte[blobSize]; - fixed (byte* pDsaBlob = &blob[0]) - { - // Build the header - BCRYPT_DSA_KEY_BLOB* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB*)pDsaBlob; - - pBcryptBlob->Magic = includePrivate ? KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC : KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC; - pBcryptBlob->cbKey = cbKey; - - int offset = sizeof(KeyBlobMagicNumber) + sizeof(int); // skip Magic and cbKey + Debug.Assert(offset == blobSize, $"Expected offset = blobSize, got {offset} != {blobSize}"); + } + } - if (parameters.Seed != null) - { - // The Seed length is hardcoded into BCRYPT_DSA_KEY_BLOB, so check it now we can give a nicer error message. - if (parameters.Seed.Length != Sha1HashOutputSize) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_SeedRestriction_ShortKey); + private static unsafe void GenerateV2DsaBlob(out byte[] blob, DSAParameters parameters, int cbKey, bool includePrivateParameters) + { + // We need to build a key blob structured as follows: + // BCRYPT_DSA_KEY_BLOB_V2 header + // byte[cbSeedLength] Seed + // byte[cbGroupSize] Q + // byte[cbKey] P + // byte[cbKey] G + // byte[cbKey] Y + // -- Private only -- + // byte[cbGroupSize] X + + int blobSize = + sizeof(BCRYPT_DSA_KEY_BLOB_V2) + + (parameters.Seed == null ? parameters.Q!.Length : parameters.Seed.Length) + // Use Q size if Seed is not present + parameters.Q!.Length + + parameters.P!.Length + + parameters.G!.Length + + parameters.Y!.Length + + (includePrivateParameters ? parameters.X!.Length : 0); + + blob = new byte[blobSize]; + fixed (byte* pDsaBlob = &blob[0]) + { + // Build the header + BCRYPT_DSA_KEY_BLOB_V2* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pDsaBlob; - Interop.BCrypt.EmitBigEndian(blob, ref offset, parameters.Counter); - Interop.BCrypt.Emit(blob, ref offset, parameters.Seed); - } - else - { - // If Seed is not present, back fill both counter and seed with 0xff. Do not use parameters.Counter as CNG is more strict than CAPI and will reject - // anything other than 0xffffffff. That could complicate efforts to switch usage of DSACryptoServiceProvider to DSACng. - Interop.BCrypt.EmitByte(blob, ref offset, 0xff, Sha1HashOutputSize + sizeof(int)); - } + pBcryptBlob->Magic = includePrivateParameters ? KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2 : KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2; + pBcryptBlob->cbKey = cbKey; - // The Q length is hardcoded into BCRYPT_DSA_KEY_BLOB, so check it now we can give a nicer error message. - if (parameters.Q!.Length != Sha1HashOutputSize) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_QRestriction_ShortKey); + // For some reason, Windows bakes the hash algorithm into the key itself. Furthermore, it demands that the Q length match the + // length of the named hash algorithm's output - otherwise, the Import fails. So we have to give it the hash algorithm that matches + // the Q length - and if there is no matching hash algorithm, we throw up our hands and throw a PlatformNotSupported. + // + // Note that this has no bearing on the hash algorithm you pass to SignData(). The class library (not Windows) hashes that according + // to the hash algorithm passed to SignData() and presents the hash result to NCryptSignHash(), truncating the hash to the Q length + // if necessary (and as demanded by the NIST spec.) Windows will be no wiser and we'll get the result we want. + pBcryptBlob->hashAlgorithm = parameters.Q.Length switch + { + Sha1HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA1, + Sha256HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA256, + Sha512HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA512, + _ => throw new PlatformNotSupportedException(SR.Cryptography_InvalidDsaParameters_QRestriction_LargeKey), + }; + pBcryptBlob->standardVersion = DSAFIPSVERSION_ENUM.DSA_FIPS186_3; - Interop.BCrypt.Emit(blob, ref offset, parameters.Q); + int offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2) - 4; //skip to Count[4] - Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB)}"); + if (parameters.Seed != null) + { + Interop.BCrypt.EmitBigEndian(blob, ref offset, parameters.Counter); + Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}"); + pBcryptBlob->cbSeedLength = parameters.Seed.Length; + pBcryptBlob->cbGroupSize = parameters.Q.Length; + Interop.BCrypt.Emit(blob, ref offset, parameters.Seed); + } + else + { + // If Seed is not present, back fill both counter and seed with 0xff. Do not use parameters.Counter as CNG is more strict than CAPI and will reject + // anything other than 0xffffffff. That could complicate efforts to switch usage of DSACryptoServiceProvider to DSACng. + Interop.BCrypt.EmitByte(blob, ref offset, 0xff, sizeof(int)); + Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}"); + int defaultSeedLength = parameters.Q.Length; + pBcryptBlob->cbSeedLength = defaultSeedLength; + pBcryptBlob->cbGroupSize = parameters.Q.Length; + Interop.BCrypt.EmitByte(blob, ref offset, 0xff, defaultSeedLength); + } - Interop.BCrypt.Emit(blob, ref offset, parameters.P!); - Interop.BCrypt.Emit(blob, ref offset, parameters.G!); - Interop.BCrypt.Emit(blob, ref offset, parameters.Y!); - if (includePrivate) - { - Interop.BCrypt.Emit(blob, ref offset, parameters.X!); - } + Interop.BCrypt.Emit(blob, ref offset, parameters.Q); + Interop.BCrypt.Emit(blob, ref offset, parameters.P); + Interop.BCrypt.Emit(blob, ref offset, parameters.G); + Interop.BCrypt.Emit(blob, ref offset, parameters.Y); - Debug.Assert(offset == blobSize, $"Expected offset = blobSize, got {offset} != {blobSize}"); + if (includePrivateParameters) + { + Interop.BCrypt.Emit(blob, ref offset, parameters.X!); } + + Debug.Assert(offset == blobSize, $"Expected offset = blobSize, got {offset} != {blobSize}"); } + } - private static unsafe void GenerateV2DsaBlob(out byte[] blob, DSAParameters parameters, int cbKey, bool includePrivateParameters) - { - // We need to build a key blob structured as follows: - // BCRYPT_DSA_KEY_BLOB_V2 header - // byte[cbSeedLength] Seed - // byte[cbGroupSize] Q - // byte[cbKey] P - // byte[cbKey] G - // byte[cbKey] Y - // -- Private only -- - // byte[cbGroupSize] X - - int blobSize = - sizeof(BCRYPT_DSA_KEY_BLOB_V2) + - (parameters.Seed == null ? parameters.Q!.Length : parameters.Seed.Length) + // Use Q size if Seed is not present - parameters.Q!.Length + - parameters.P!.Length + - parameters.G!.Length + - parameters.Y!.Length + - (includePrivateParameters ? parameters.X!.Length : 0); - - blob = new byte[blobSize]; - fixed (byte* pDsaBlob = &blob[0]) - { - // Build the header - BCRYPT_DSA_KEY_BLOB_V2* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pDsaBlob; - - pBcryptBlob->Magic = includePrivateParameters ? KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2 : KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2; - pBcryptBlob->cbKey = cbKey; - - // For some reason, Windows bakes the hash algorithm into the key itself. Furthermore, it demands that the Q length match the - // length of the named hash algorithm's output - otherwise, the Import fails. So we have to give it the hash algorithm that matches - // the Q length - and if there is no matching hash algorithm, we throw up our hands and throw a PlatformNotSupported. - // - // Note that this has no bearing on the hash algorithm you pass to SignData(). The class library (not Windows) hashes that according - // to the hash algorithm passed to SignData() and presents the hash result to NCryptSignHash(), truncating the hash to the Q length - // if necessary (and as demanded by the NIST spec.) Windows will be no wiser and we'll get the result we want. - pBcryptBlob->hashAlgorithm = parameters.Q.Length switch - { - Sha1HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA1, - Sha256HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA256, - Sha512HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA512, - _ => throw new PlatformNotSupportedException(SR.Cryptography_InvalidDsaParameters_QRestriction_LargeKey), - }; - pBcryptBlob->standardVersion = DSAFIPSVERSION_ENUM.DSA_FIPS186_3; + public override DSAParameters ExportParameters(bool includePrivateParameters) + { + byte[] dsaBlob = ExportKeyBlob(includePrivateParameters); - int offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2) - 4; //skip to Count[4] + KeyBlobMagicNumber magic = (KeyBlobMagicNumber)BitConverter.ToInt32(dsaBlob, 0); - if (parameters.Seed != null) - { - Interop.BCrypt.EmitBigEndian(blob, ref offset, parameters.Counter); - Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}"); - pBcryptBlob->cbSeedLength = parameters.Seed.Length; - pBcryptBlob->cbGroupSize = parameters.Q.Length; - Interop.BCrypt.Emit(blob, ref offset, parameters.Seed); - } - else - { - // If Seed is not present, back fill both counter and seed with 0xff. Do not use parameters.Counter as CNG is more strict than CAPI and will reject - // anything other than 0xffffffff. That could complicate efforts to switch usage of DSACryptoServiceProvider to DSACng. - Interop.BCrypt.EmitByte(blob, ref offset, 0xff, sizeof(int)); - Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}"); - int defaultSeedLength = parameters.Q.Length; - pBcryptBlob->cbSeedLength = defaultSeedLength; - pBcryptBlob->cbGroupSize = parameters.Q.Length; - Interop.BCrypt.EmitByte(blob, ref offset, 0xff, defaultSeedLength); - } + // Check the magic value in the key blob header. If the blob does not have the required magic, + // then throw a CryptographicException. + CheckMagicValueOfKey(magic, includePrivateParameters); - Interop.BCrypt.Emit(blob, ref offset, parameters.Q); - Interop.BCrypt.Emit(blob, ref offset, parameters.P); - Interop.BCrypt.Emit(blob, ref offset, parameters.G); - Interop.BCrypt.Emit(blob, ref offset, parameters.Y); + unsafe + { + DSAParameters dsaParams = default; - if (includePrivateParameters) + fixed (byte* pDsaBlob = dsaBlob) + { + int offset; + if (magic == KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC || magic == KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC) { - Interop.BCrypt.Emit(blob, ref offset, parameters.X!); + if (dsaBlob.Length < sizeof(BCRYPT_DSA_KEY_BLOB)) + throw ErrorCode.E_FAIL.ToCryptographicException(); + + BCRYPT_DSA_KEY_BLOB* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB*)pDsaBlob; + // We now have a buffer laid out as follows: + // BCRYPT_DSA_KEY_BLOB header + // byte[cbKey] P + // byte[cbKey] G + // byte[cbKey] Y + // -- Private only -- + // byte[Sha1HashOutputSize] X + + offset = sizeof(KeyBlobMagicNumber) + sizeof(int); // skip Magic and cbKey + + // Read out a (V1) BCRYPT_DSA_KEY_BLOB structure. + dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4)); + dsaParams.Seed = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize); + dsaParams.Q = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize); + + Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB)}"); + dsaParams.P = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); + dsaParams.G = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); + dsaParams.Y = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); + if (includePrivateParameters) + { + dsaParams.X = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize); + } } + else + { + Debug.Assert(magic == KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2 || magic == KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2); - Debug.Assert(offset == blobSize, $"Expected offset = blobSize, got {offset} != {blobSize}"); - } - } + if (dsaBlob.Length < sizeof(BCRYPT_DSA_KEY_BLOB_V2)) + throw ErrorCode.E_FAIL.ToCryptographicException(); - public override DSAParameters ExportParameters(bool includePrivateParameters) - { - byte[] dsaBlob = ExportKeyBlob(includePrivateParameters); + BCRYPT_DSA_KEY_BLOB_V2* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pDsaBlob; + // We now have a buffer laid out as follows: + // BCRYPT_DSA_KEY_BLOB_V2 header + // byte[cbSeedLength] Seed + // byte[cbGroupSize] Q + // byte[cbKey] P + // byte[cbKey] G + // byte[cbKey] Y + // -- Private only -- + // byte[cbGroupSize] X - KeyBlobMagicNumber magic = (KeyBlobMagicNumber)BitConverter.ToInt32(dsaBlob, 0); + offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2) - 4; //skip to Count[4] - // Check the magic value in the key blob header. If the blob does not have the required magic, - // then throw a CryptographicException. - CheckMagicValueOfKey(magic, includePrivateParameters); + // Read out a BCRYPT_DSA_KEY_BLOB_V2 structure. + dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4)); - unsafe - { - DSAParameters dsaParams = default; + Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}"); - fixed (byte* pDsaBlob = dsaBlob) - { - int offset; - if (magic == KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC || magic == KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC) - { - if (dsaBlob.Length < sizeof(BCRYPT_DSA_KEY_BLOB)) - throw ErrorCode.E_FAIL.ToCryptographicException(); - - BCRYPT_DSA_KEY_BLOB* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB*)pDsaBlob; - // We now have a buffer laid out as follows: - // BCRYPT_DSA_KEY_BLOB header - // byte[cbKey] P - // byte[cbKey] G - // byte[cbKey] Y - // -- Private only -- - // byte[Sha1HashOutputSize] X - - offset = sizeof(KeyBlobMagicNumber) + sizeof(int); // skip Magic and cbKey - - // Read out a (V1) BCRYPT_DSA_KEY_BLOB structure. - dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4)); - dsaParams.Seed = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize); - dsaParams.Q = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize); - - Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB)}"); - dsaParams.P = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); - dsaParams.G = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); - dsaParams.Y = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); - if (includePrivateParameters) - { - dsaParams.X = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize); - } - } - else + dsaParams.Seed = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbSeedLength); + dsaParams.Q = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbGroupSize); + dsaParams.P = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); + dsaParams.G = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); + dsaParams.Y = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); + if (includePrivateParameters) { - Debug.Assert(magic == KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2 || magic == KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2); - - if (dsaBlob.Length < sizeof(BCRYPT_DSA_KEY_BLOB_V2)) - throw ErrorCode.E_FAIL.ToCryptographicException(); - - BCRYPT_DSA_KEY_BLOB_V2* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pDsaBlob; - // We now have a buffer laid out as follows: - // BCRYPT_DSA_KEY_BLOB_V2 header - // byte[cbSeedLength] Seed - // byte[cbGroupSize] Q - // byte[cbKey] P - // byte[cbKey] G - // byte[cbKey] Y - // -- Private only -- - // byte[cbGroupSize] X - - offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2) - 4; //skip to Count[4] - - // Read out a BCRYPT_DSA_KEY_BLOB_V2 structure. - dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4)); - - Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}"); - - dsaParams.Seed = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbSeedLength); - dsaParams.Q = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbGroupSize); - dsaParams.P = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); - dsaParams.G = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); - dsaParams.Y = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey); - if (includePrivateParameters) - { - dsaParams.X = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbGroupSize); - } + dsaParams.X = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbGroupSize); } + } - // If no counter/seed information is present, normalize Counter and Seed to 0/null to maintain parity with the CAPI version of DSA. - if (dsaParams.Counter == -1) - { - dsaParams.Counter = 0; - dsaParams.Seed = null; - } + // If no counter/seed information is present, normalize Counter and Seed to 0/null to maintain parity with the CAPI version of DSA. + if (dsaParams.Counter == -1) + { + dsaParams.Counter = 0; + dsaParams.Seed = null; + } - Debug.Assert(offset == dsaBlob.Length, $"Expected offset = dsaBlob.Length, got {offset} != {dsaBlob.Length}"); + Debug.Assert(offset == dsaBlob.Length, $"Expected offset = dsaBlob.Length, got {offset} != {dsaBlob.Length}"); - return dsaParams; - } + return dsaParams; } } + } - /// - /// This function checks the magic value in the key blob header - /// - /// The expected magic number. - /// Private blob if true else public key blob - private static void CheckMagicValueOfKey(KeyBlobMagicNumber magic, bool includePrivateParameters) + /// + /// This function checks the magic value in the key blob header + /// + /// The expected magic number. + /// Private blob if true else public key blob + private static void CheckMagicValueOfKey(KeyBlobMagicNumber magic, bool includePrivateParameters) + { + if (includePrivateParameters) { - if (includePrivateParameters) - { - if (magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC && magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2) - throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); - } - else - { - if (magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC && magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2) - throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); - } + if (magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC && magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2) + throw new CryptographicException(SR.Cryptography_NotValidPrivateKey); + } + else + { + if (magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC && magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2) + throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); } - } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS + } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSACng.SignVerify.cs b/src/libraries/Common/src/System/Security/Cryptography/DSACng.SignVerify.cs index 7971a35a2adf9d..9393dc735880f4 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/DSACng.SignVerify.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/DSACng.SignVerify.cs @@ -9,199 +9,174 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class DSAImplementation + public sealed partial class DSACng : DSA { -#endif - public sealed partial class DSACng : DSA - { - // As of FIPS 186-4 the maximum Q size is 32 bytes. - // - // See also: cbGroupSize at - // https://docs.microsoft.com/en-us/windows/desktop/api/bcrypt/ns-bcrypt-_bcrypt_dsa_key_blob_v2 - private const int WindowsMaxQSize = 32; + // As of FIPS 186-4 the maximum Q size is 32 bytes. + // + // See also: cbGroupSize at + // https://docs.microsoft.com/en-us/windows/desktop/api/bcrypt/ns-bcrypt-_bcrypt_dsa_key_blob_v2 + private const int WindowsMaxQSize = 32; - public override byte[] CreateSignature(byte[] rgbHash) + public override byte[] CreateSignature(byte[] rgbHash) + { + if (rgbHash == null) { - if (rgbHash == null) - { - throw new ArgumentNullException(nameof(rgbHash)); - } - - Span stackBuf = stackalloc byte[WindowsMaxQSize]; - ReadOnlySpan source = AdjustHashSizeIfNecessary(rgbHash, stackBuf); - - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - unsafe - { - return CngCommon.SignHash(keyHandle, source, AsymmetricPaddingMode.None, null, source.Length * 2); - } - } + throw new ArgumentNullException(nameof(rgbHash)); } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - protected override unsafe bool TryCreateSignatureCore( - ReadOnlySpan hash, - Span destination, - DSASignatureFormat signatureFormat, - out int bytesWritten) -#else - public override unsafe bool TryCreateSignature(ReadOnlySpan hash, Span destination, out int bytesWritten) -#endif - { - Span stackBuf = stackalloc byte[WindowsMaxQSize]; - ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf); + Span stackBuf = stackalloc byte[WindowsMaxQSize]; + ReadOnlySpan source = AdjustHashSizeIfNecessary(rgbHash, stackBuf); - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) + using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) + { + unsafe { - if (!CngCommon.TrySignHash(keyHandle, source, destination, AsymmetricPaddingMode.None, null, out bytesWritten)) - { - bytesWritten = 0; - return false; - } + return CngCommon.SignHash(keyHandle, source, AsymmetricPaddingMode.None, null, source.Length * 2); } + } + } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) - { - return true; - } + protected override unsafe bool TryCreateSignatureCore( + ReadOnlySpan hash, + Span destination, + DSASignatureFormat signatureFormat, + out int bytesWritten) + { + Span stackBuf = stackalloc byte[WindowsMaxQSize]; + ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf); - if (signatureFormat != DSASignatureFormat.Rfc3279DerSequence) + using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) + { + if (!CngCommon.TrySignHash(keyHandle, source, destination, AsymmetricPaddingMode.None, null, out bytesWritten)) { - Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); - throw new CryptographicException( - SR.Cryptography_UnknownSignatureFormat, - signatureFormat.ToString()); + bytesWritten = 0; + return false; } + } - return AsymmetricAlgorithmHelpers.TryConvertIeee1363ToDer( - destination.Slice(0, bytesWritten), - destination, - out bytesWritten); -#else + if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) + { return true; -#endif } - public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) + if (signatureFormat != DSASignatureFormat.Rfc3279DerSequence) { - if (rgbHash == null) - { - throw new ArgumentNullException(nameof(rgbHash)); - } - if (rgbSignature == null) - { - throw new ArgumentNullException(nameof(rgbSignature)); - } + Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); + throw new CryptographicException( + SR.Cryptography_UnknownSignatureFormat, + signatureFormat.ToString()); + } + + return AsymmetricAlgorithmHelpers.TryConvertIeee1363ToDer( + destination.Slice(0, bytesWritten), + destination, + out bytesWritten); + } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - return VerifySignatureCore(rgbHash, rgbSignature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation); -#else - return VerifySignature((ReadOnlySpan)rgbHash, (ReadOnlySpan)rgbSignature); -#endif + public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) + { + if (rgbHash == null) + { + throw new ArgumentNullException(nameof(rgbHash)); + } + if (rgbSignature == null) + { + throw new ArgumentNullException(nameof(rgbSignature)); } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - protected override bool VerifySignatureCore( - ReadOnlySpan hash, - ReadOnlySpan signature, - DSASignatureFormat signatureFormat) + return VerifySignatureCore(rgbHash, rgbSignature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation); + } + + protected override bool VerifySignatureCore( + ReadOnlySpan hash, + ReadOnlySpan signature, + DSASignatureFormat signatureFormat) + { + Span stackBuf = stackalloc byte[WindowsMaxQSize]; + ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf); + + if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) { - Span stackBuf = stackalloc byte[WindowsMaxQSize]; - ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf); + // source.Length is the field size, in bytes, so just convert to bits. + int fieldSizeBits = source.Length * 8; + signature = this.ConvertSignatureToIeeeP1363(signatureFormat, signature, fieldSizeBits); + } + else if (signatureFormat != DSASignatureFormat.IeeeP1363FixedFieldConcatenation) + { + Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); + throw new CryptographicException( + SR.Cryptography_UnknownSignatureFormat, + signatureFormat.ToString()); + } - if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) - { - // source.Length is the field size, in bytes, so just convert to bits. - int fieldSizeBits = source.Length * 8; - signature = this.ConvertSignatureToIeeeP1363(signatureFormat, signature, fieldSizeBits); - } - else if (signatureFormat != DSASignatureFormat.IeeeP1363FixedFieldConcatenation) - { - Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); - throw new CryptographicException( - SR.Cryptography_UnknownSignatureFormat, - signatureFormat.ToString()); - } -#else - public override bool VerifySignature(ReadOnlySpan hash, ReadOnlySpan signature) + using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) { - Span stackBuf = stackalloc byte[WindowsMaxQSize]; - ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf); -#endif - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) + unsafe { - unsafe - { - return CngCommon.VerifyHash(keyHandle, source, signature, AsymmetricPaddingMode.None, null); - } + return CngCommon.VerifyHash(keyHandle, source, signature, AsymmetricPaddingMode.None, null); } } + } - private ReadOnlySpan AdjustHashSizeIfNecessary(ReadOnlySpan hash, Span stackBuf) - { - Debug.Assert(stackBuf.Length == WindowsMaxQSize); + private ReadOnlySpan AdjustHashSizeIfNecessary(ReadOnlySpan hash, Span stackBuf) + { + Debug.Assert(stackBuf.Length == WindowsMaxQSize); - // Windows CNG requires that the hash output and q match sizes, but we can better - // interoperate with other FIPS 186-3 implementations if we perform truncation - // here, before sending it to CNG. Since this is a scenario presented in the - // CAVP reference test suite, we can confirm our implementation. - // - // If, on the other hand, Q is too big, we need to left-pad the hash with zeroes - // (since it gets treated as a big-endian number). Since this is also a scenario - // presented in the CAVP reference test suite, we can confirm our implementation. + // Windows CNG requires that the hash output and q match sizes, but we can better + // interoperate with other FIPS 186-3 implementations if we perform truncation + // here, before sending it to CNG. Since this is a scenario presented in the + // CAVP reference test suite, we can confirm our implementation. + // + // If, on the other hand, Q is too big, we need to left-pad the hash with zeroes + // (since it gets treated as a big-endian number). Since this is also a scenario + // presented in the CAVP reference test suite, we can confirm our implementation. - int qLength = ComputeQLength(); - Debug.Assert(qLength <= WindowsMaxQSize); + int qLength = ComputeQLength(); + Debug.Assert(qLength <= WindowsMaxQSize); - if (qLength == hash.Length) - { - return hash; - } + if (qLength == hash.Length) + { + return hash; + } - if (qLength < hash.Length) - { - return hash.Slice(0, qLength); - } + if (qLength < hash.Length) + { + return hash.Slice(0, qLength); + } + + int zeroByteCount = qLength - hash.Length; + stackBuf.Slice(0, zeroByteCount).Clear(); + hash.CopyTo(stackBuf.Slice(zeroByteCount)); + return stackBuf.Slice(0, qLength); + } - int zeroByteCount = qLength - hash.Length; - stackBuf.Slice(0, zeroByteCount).Clear(); - hash.CopyTo(stackBuf.Slice(zeroByteCount)); - return stackBuf.Slice(0, qLength); + private int ComputeQLength() + { + byte[] blob; + using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) + { + blob = this.ExportKeyBlob(false); } - private int ComputeQLength() + unsafe { - byte[] blob; - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) + if (blob.Length < sizeof(BCRYPT_DSA_KEY_BLOB_V2)) { - blob = this.ExportKeyBlob(false); + return Sha1HashOutputSize; } - unsafe + fixed (byte* pBlobBytes = blob) { - if (blob.Length < sizeof(BCRYPT_DSA_KEY_BLOB_V2)) + BCRYPT_DSA_KEY_BLOB_V2* pBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pBlobBytes; + if (pBlob->Magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2 && pBlob->Magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2) { + // This is a V1 BCRYPT_DSA_KEY_BLOB, which hardcodes the Q length to 20 bytes. return Sha1HashOutputSize; } - fixed (byte* pBlobBytes = blob) - { - BCRYPT_DSA_KEY_BLOB_V2* pBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pBlobBytes; - if (pBlob->Magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2 && pBlob->Magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2) - { - // This is a V1 BCRYPT_DSA_KEY_BLOB, which hardcodes the Q length to 20 bytes. - return Sha1HashOutputSize; - } - - return pBlob->cbGroupSize; - } + return pBlob->cbGroupSize; } } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSACng.cs b/src/libraries/Common/src/System/Security/Cryptography/DSACng.cs index a89f2706a23d43..d9f8ed5cafa680 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/DSACng.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/DSACng.cs @@ -5,84 +5,80 @@ using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; +using System.Runtime.Versioning; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class DSAImplementation + public sealed partial class DSACng : DSA { -#endif - public sealed partial class DSACng : DSA + /// + /// Create a DSACng algorithm with a random 2048 bit key pair. + /// + [SupportedOSPlatform("windows")] + public DSACng() + : this(keySize: s_defaultKeySize) { - /// - /// Create a DSACng algorithm with a random 2048 bit key pair. - /// - public DSACng() - : this(keySize: s_defaultKeySize) - { - } + } - /// - /// Creates a new DSACng object that will use a randomly generated key of the specified size. - /// Valid key sizes range from 512 to 3072 bits, in increments of 64. It's suggested that a - /// minimum size of 2048 bits be used for all keys. - /// - /// Size of the key to generate, in bits. - /// if is not valid - public DSACng(int keySize) - { - LegalKeySizesValue = s_legalKeySizes; - KeySize = keySize; - } + /// + /// Creates a new DSACng object that will use a randomly generated key of the specified size. + /// Valid key sizes range from 512 to 3072 bits, in increments of 64. It's suggested that a + /// minimum size of 2048 bits be used for all keys. + /// + /// Size of the key to generate, in bits. + /// if is not valid + [SupportedOSPlatform("windows")] + public DSACng(int keySize) + { + LegalKeySizesValue = s_legalKeySizes; + KeySize = keySize; + } - public override KeySizes[] LegalKeySizes + public override KeySizes[] LegalKeySizes + { + get { - get - { - return base.LegalKeySizes; - } + return base.LegalKeySizes; } + } - public override string SignatureAlgorithm => "DSA"; - public override string? KeyExchangeAlgorithm => null; - - // Need to override since base methods throw a "override me" exception: makes SignData/VerifyData function. - protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => - CngCommon.HashData(data, offset, count, hashAlgorithm); + public override string SignatureAlgorithm => "DSA"; + public override string? KeyExchangeAlgorithm => null; - protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => - CngCommon.HashData(data, hashAlgorithm); + // Need to override since base methods throw a "override me" exception: makes SignData/VerifyData function. + protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => + CngCommon.HashData(data, offset, count, hashAlgorithm); - protected override bool TryHashData(ReadOnlySpan source, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) => - CngCommon.TryHashData(source, destination, hashAlgorithm, out bytesWritten); + protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => + CngCommon.HashData(data, hashAlgorithm); - private void ForceSetKeySize(int newKeySize) - { - // Our LegalKeySizes value stores the values that we encoded as being the correct - // legal key size limitations for this algorithm, as documented on MSDN. - // - // But on a new OS version we might not question if our limit is accurate, or MSDN - // could have been inaccurate to start with. - // - // Since the key is already loaded, we know that Windows thought it to be valid; - // therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance - // check. - // - KeySizeValue = newKeySize; - } + protected override bool TryHashData(ReadOnlySpan source, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) => + CngCommon.TryHashData(source, destination, hashAlgorithm, out bytesWritten); - private static bool Supports2048KeySize() - { - Debug.Assert(OperatingSystem.IsWindows()); - Version version = Environment.OSVersion.Version; - bool isAtLeastWindows8 = version.Major > 6 || (version.Major == 6 && version.Minor >= 2); - return isAtLeastWindows8; - } + private void ForceSetKeySize(int newKeySize) + { + // Our LegalKeySizes value stores the values that we encoded as being the correct + // legal key size limitations for this algorithm, as documented on MSDN. + // + // But on a new OS version we might not question if our limit is accurate, or MSDN + // could have been inaccurate to start with. + // + // Since the key is already loaded, we know that Windows thought it to be valid; + // therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance + // check. + // + KeySizeValue = newKeySize; + } - private static readonly KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(minSize: 512, maxSize: 3072, skipSize: 64) }; - private static readonly int s_defaultKeySize = Supports2048KeySize() ? 2048 : 1024; + private static bool Supports2048KeySize() + { + Debug.Assert(OperatingSystem.IsWindows()); + Version version = Environment.OSVersion.Version; + bool isAtLeastWindows8 = version.Major > 6 || (version.Major == 6 && version.Minor >= 2); + return isAtLeastWindows8; } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS + + private static readonly KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(minSize: 512, maxSize: 3072, skipSize: 64) }; + private static readonly int s_defaultKeySize = Supports2048KeySize() ? 2048 : 1024; } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSAOpenSsl.cs b/src/libraries/Common/src/System/Security/Cryptography/DSAOpenSsl.cs index d51e1a3a8e5d3e..8a8445fe17f5b3 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/DSAOpenSsl.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/DSAOpenSsl.cs @@ -3,425 +3,400 @@ using System.Diagnostics; using System.IO; +using System.Runtime.Versioning; using Internal.Cryptography; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - public partial class DSA : AsymmetricAlgorithm + public sealed partial class DSAOpenSsl : DSA { - private static DSA CreateCore() + // The biggest key allowed by FIPS 186-4 has N=256 (bit), which + // maximally produces a 72-byte DER signature. + // If a future version of the standard continues to enhance DSA, + // we may want to bump this limit to allow the max-1 (expected size) + // TryCreateSignature to pass. + // Future updates seem unlikely, though, as FIPS 186-5 October 2019 draft has + // DSA as a no longer supported/updated algorithm. + private const int SignatureStackBufSize = 72; + private const int BitsPerByte = 8; + + private Lazy _key = null!; + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public DSAOpenSsl() + : this(2048) { - return new DSAImplementation.DSAOpenSsl(); } - } - internal static partial class DSAImplementation - { -#endif - public sealed partial class DSAOpenSsl : DSA + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public DSAOpenSsl(int keySize) { - // The biggest key allowed by FIPS 186-4 has N=256 (bit), which - // maximally produces a 72-byte DER signature. - // If a future version of the standard continues to enhance DSA, - // we may want to bump this limit to allow the max-1 (expected size) - // TryCreateSignature to pass. - // Future updates seem unlikely, though, as FIPS 186-5 October 2019 draft has - // DSA as a no longer supported/updated algorithm. - private const int SignatureStackBufSize = 72; - private const int BitsPerByte = 8; - - private Lazy _key = null!; - - public DSAOpenSsl() - : this(2048) - { - } - - public DSAOpenSsl(int keySize) - { - ThrowIfNotSupported(); - LegalKeySizesValue = s_legalKeySizes; - base.KeySize = keySize; - _key = new Lazy(GenerateKey); - } + ThrowIfNotSupported(); + LegalKeySizesValue = s_legalKeySizes; + base.KeySize = keySize; + _key = new Lazy(GenerateKey); + } - public override int KeySize + public override int KeySize + { + set { - set + if (KeySize == value) { - if (KeySize == value) - { - return; - } + return; + } - // Set the KeySize before FreeKey so that an invalid value doesn't throw away the key - base.KeySize = value; + // Set the KeySize before FreeKey so that an invalid value doesn't throw away the key + base.KeySize = value; - ThrowIfDisposed(); - FreeKey(); - _key = new Lazy(GenerateKey); - } + ThrowIfDisposed(); + FreeKey(); + _key = new Lazy(GenerateKey); } + } - private void ForceSetKeySize(int newKeySize) - { - // In the event that a key was loaded via ImportParameters or an IntPtr/SafeHandle - // it could be outside of the bounds that we currently represent as "legal key sizes". - // Since that is our view into the underlying component it can be detached from the - // component's understanding. If it said it has opened a key, and this is the size, trust it. - KeySizeValue = newKeySize; - } + private void ForceSetKeySize(int newKeySize) + { + // In the event that a key was loaded via ImportParameters or an IntPtr/SafeHandle + // it could be outside of the bounds that we currently represent as "legal key sizes". + // Since that is our view into the underlying component it can be detached from the + // component's understanding. If it said it has opened a key, and this is the size, trust it. + KeySizeValue = newKeySize; + } - public override KeySizes[] LegalKeySizes + public override KeySizes[] LegalKeySizes + { + get { - get - { - return base.LegalKeySizes; - } + return base.LegalKeySizes; } + } - public override DSAParameters ExportParameters(bool includePrivateParameters) - { - // It's entirely possible that this line will cause the key to be generated in the first place. - SafeDsaHandle key = GetKey(); - - DSAParameters dsaParameters = Interop.Crypto.ExportDsaParameters(key, includePrivateParameters); - bool hasPrivateKey = dsaParameters.X != null; - - if (hasPrivateKey != includePrivateParameters) - throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); + public override DSAParameters ExportParameters(bool includePrivateParameters) + { + // It's entirely possible that this line will cause the key to be generated in the first place. + SafeDsaHandle key = GetKey(); - return dsaParameters; - } + DSAParameters dsaParameters = Interop.Crypto.ExportDsaParameters(key, includePrivateParameters); + bool hasPrivateKey = dsaParameters.X != null; - public override void ImportParameters(DSAParameters parameters) - { - if (parameters.P == null || parameters.Q == null || parameters.G == null || parameters.Y == null) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MissingFields); + if (hasPrivateKey != includePrivateParameters) + throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); - // J is not required and is not even used on CNG blobs. It should however be less than P (J == (P-1) / Q). This validation check - // is just to maintain parity with DSACNG and DSACryptoServiceProvider, which also perform this check. - if (parameters.J != null && parameters.J.Length >= parameters.P.Length) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPJ); + return dsaParameters; + } - bool hasPrivateKey = parameters.X != null; + public override void ImportParameters(DSAParameters parameters) + { + if (parameters.P == null || parameters.Q == null || parameters.G == null || parameters.Y == null) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MissingFields); - int keySize = parameters.P.Length; - if (parameters.G.Length != keySize || parameters.Y.Length != keySize) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPGY); + // J is not required and is not even used on CNG blobs. It should however be less than P (J == (P-1) / Q). This validation check + // is just to maintain parity with DSACNG and DSACryptoServiceProvider, which also perform this check. + if (parameters.J != null && parameters.J.Length >= parameters.P.Length) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPJ); - if (hasPrivateKey && parameters.X!.Length != parameters.Q.Length) - throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX); + bool hasPrivateKey = parameters.X != null; - ThrowIfDisposed(); + int keySize = parameters.P.Length; + if (parameters.G.Length != keySize || parameters.Y.Length != keySize) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPGY); - SafeDsaHandle key; - if (!Interop.Crypto.DsaKeyCreateByExplicitParameters( - out key, - parameters.P, parameters.P.Length, - parameters.Q, parameters.Q.Length, - parameters.G, parameters.G.Length, - parameters.Y, parameters.Y.Length, - parameters.X, parameters.X != null ? parameters.X.Length : 0)) - { - throw Interop.Crypto.CreateOpenSslCryptographicException(); - } + if (hasPrivateKey && parameters.X!.Length != parameters.Q.Length) + throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX); - SetKey(key); - } + ThrowIfDisposed(); - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - ReadOnlySpan source, - out int bytesRead) + SafeDsaHandle key; + if (!Interop.Crypto.DsaKeyCreateByExplicitParameters( + out key, + parameters.P, parameters.P.Length, + parameters.Q, parameters.Q.Length, + parameters.G, parameters.G.Length, + parameters.Y, parameters.Y.Length, + parameters.X, parameters.X != null ? parameters.X.Length : 0)) { - ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + throw Interop.Crypto.CreateOpenSslCryptographicException(); } - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - ReadOnlySpan source, - out int bytesRead) - { - ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); - } + SetKey(key); + } - protected override void Dispose(bool disposing) - { - if (disposing) - { - FreeKey(); - _key = null!; - } + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + } - base.Dispose(disposing); - } + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + } - private void FreeKey() + protected override void Dispose(bool disposing) + { + if (disposing) { - if (_key != null && _key.IsValueCreated) - { - SafeDsaHandle handle = _key.Value; - - if (handle != null) - { - handle.Dispose(); - } - } + FreeKey(); + _key = null!; } - private static void CheckInvalidKey(SafeDsaHandle key) + base.Dispose(disposing); + } + + private void FreeKey() + { + if (_key != null && _key.IsValueCreated) { - if (key == null || key.IsInvalid) + SafeDsaHandle handle = _key.Value; + + if (handle != null) { - throw new CryptographicException(SR.Cryptography_OpenInvalidHandle); + handle.Dispose(); } } + } - private SafeDsaHandle GenerateKey() + private static void CheckInvalidKey(SafeDsaHandle key) + { + if (key == null || key.IsInvalid) { - SafeDsaHandle key; + throw new CryptographicException(SR.Cryptography_OpenInvalidHandle); + } + } - if (!Interop.Crypto.DsaGenerateKey(out key, KeySize)) - { - throw Interop.Crypto.CreateOpenSslCryptographicException(); - } + private SafeDsaHandle GenerateKey() + { + SafeDsaHandle key; - return key; + if (!Interop.Crypto.DsaGenerateKey(out key, KeySize)) + { + throw Interop.Crypto.CreateOpenSslCryptographicException(); } - protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) - { - // we're sealed and the base should have checked this already - Debug.Assert(data != null); - Debug.Assert(offset >= 0 && offset <= data.Length); - Debug.Assert(count >= 0 && count <= data.Length); - Debug.Assert(!string.IsNullOrEmpty(hashAlgorithm.Name)); + return key; + } - return AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm); - } + protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) + { + // we're sealed and the base should have checked this already + Debug.Assert(data != null); + Debug.Assert(offset >= 0 && offset <= data.Length); + Debug.Assert(count >= 0 && count <= data.Length); + Debug.Assert(!string.IsNullOrEmpty(hashAlgorithm.Name)); - protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => - AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm); + return AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm); + } - protected override bool TryHashData(ReadOnlySpan data, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) => - AsymmetricAlgorithmHelpers.TryHashData(data, destination, hashAlgorithm, out bytesWritten); + protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => + AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm); - public override byte[] CreateSignature(byte[] rgbHash) - { - if (rgbHash == null) - throw new ArgumentNullException(nameof(rgbHash)); + protected override bool TryHashData(ReadOnlySpan data, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) => + AsymmetricAlgorithmHelpers.TryHashData(data, destination, hashAlgorithm, out bytesWritten); - SafeDsaHandle key = GetKey(); - int signatureSize = Interop.Crypto.DsaEncodedSignatureSize(key); - int signatureFieldSize = Interop.Crypto.DsaSignatureFieldSize(key) * BitsPerByte; - Span signDestination = stackalloc byte[SignatureStackBufSize]; + public override byte[] CreateSignature(byte[] rgbHash) + { + if (rgbHash == null) + throw new ArgumentNullException(nameof(rgbHash)); - ReadOnlySpan derSignature = SignHash(rgbHash, signDestination, signatureSize, key); - return AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, signatureFieldSize); - } + SafeDsaHandle key = GetKey(); + int signatureSize = Interop.Crypto.DsaEncodedSignatureSize(key); + int signatureFieldSize = Interop.Crypto.DsaSignatureFieldSize(key) * BitsPerByte; + Span signDestination = stackalloc byte[SignatureStackBufSize]; -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - public override bool TryCreateSignature( - ReadOnlySpan hash, - Span destination, - out int bytesWritten) - { - return TryCreateSignatureCore( - hash, - destination, - DSASignatureFormat.IeeeP1363FixedFieldConcatenation, - out bytesWritten); - } + ReadOnlySpan derSignature = SignHash(rgbHash, signDestination, signatureSize, key); + return AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, signatureFieldSize); + } + + public override bool TryCreateSignature( + ReadOnlySpan hash, + Span destination, + out int bytesWritten) + { + return TryCreateSignatureCore( + hash, + destination, + DSASignatureFormat.IeeeP1363FixedFieldConcatenation, + out bytesWritten); + } + + protected override bool TryCreateSignatureCore( + ReadOnlySpan hash, + Span destination, + DSASignatureFormat signatureFormat, + out int bytesWritten) + { + SafeDsaHandle key = GetKey(); + int maxSignatureSize = Interop.Crypto.DsaEncodedSignatureSize(key); + Span signDestination = stackalloc byte[SignatureStackBufSize]; - protected override bool TryCreateSignatureCore( - ReadOnlySpan hash, - Span destination, - DSASignatureFormat signatureFormat, - out int bytesWritten) -#else - public override bool TryCreateSignature(ReadOnlySpan hash, Span destination, out int bytesWritten) -#endif + if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { - SafeDsaHandle key = GetKey(); - int maxSignatureSize = Interop.Crypto.DsaEncodedSignatureSize(key); - Span signDestination = stackalloc byte[SignatureStackBufSize]; + int fieldSizeBytes = Interop.Crypto.DsaSignatureFieldSize(key); + int p1363SignatureSize = 2 * fieldSizeBytes; -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) -#endif + if (destination.Length < p1363SignatureSize) { - int fieldSizeBytes = Interop.Crypto.DsaSignatureFieldSize(key); - int p1363SignatureSize = 2 * fieldSizeBytes; - - if (destination.Length < p1363SignatureSize) - { - bytesWritten = 0; - return false; - } + bytesWritten = 0; + return false; + } - int fieldSizeBits = fieldSizeBytes * 8; + int fieldSizeBits = fieldSizeBytes * 8; - ReadOnlySpan derSignature = SignHash(hash, signDestination, maxSignatureSize, key); - bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, fieldSizeBits, destination); - Debug.Assert(bytesWritten == p1363SignatureSize); - return true; - } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) + ReadOnlySpan derSignature = SignHash(hash, signDestination, maxSignatureSize, key); + bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, fieldSizeBits, destination); + Debug.Assert(bytesWritten == p1363SignatureSize); + return true; + } + else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) + { + if (destination.Length >= maxSignatureSize) { - if (destination.Length >= maxSignatureSize) - { - signDestination = destination; - } - else if (maxSignatureSize > signDestination.Length) - { - Debug.Fail($"Stack-based signDestination is insufficient ({maxSignatureSize} needed)"); - bytesWritten = 0; - return false; - } - - ReadOnlySpan derSignature = SignHash(hash, signDestination, maxSignatureSize, key); - - if (destination == signDestination) - { - bytesWritten = derSignature.Length; - return true; - } - - return Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten); + signDestination = destination; } - else + else if (maxSignatureSize > signDestination.Length) { - Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); - throw new CryptographicException( - SR.Cryptography_UnknownSignatureFormat, - signatureFormat.ToString()); + Debug.Fail($"Stack-based signDestination is insufficient ({maxSignatureSize} needed)"); + bytesWritten = 0; + return false; } -#endif - } - private static ReadOnlySpan SignHash( - ReadOnlySpan hash, - Span destination, - int signatureLength, - SafeDsaHandle key) - { - if (signatureLength > destination.Length) - { - Debug.Fail($"Stack-based signDestination is insufficient ({signatureLength} needed)"); - destination = new byte[signatureLength]; - } + ReadOnlySpan derSignature = SignHash(hash, signDestination, maxSignatureSize, key); - if (!Interop.Crypto.DsaSign(key, hash, destination, out int actualLength)) + if (destination == signDestination) { - throw Interop.Crypto.CreateOpenSslCryptographicException(); + bytesWritten = derSignature.Length; + return true; } - Debug.Assert( - actualLength <= signatureLength, - "DSA_sign reported an unexpected signature size", - "DSA_sign reported signatureSize was {0}, when <= {1} was expected", - actualLength, - signatureLength); - - return destination.Slice(0, actualLength); + return Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten); } + else + { + Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); + throw new CryptographicException( + SR.Cryptography_UnknownSignatureFormat, + signatureFormat.ToString()); + } + } - public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) + private static ReadOnlySpan SignHash( + ReadOnlySpan hash, + Span destination, + int signatureLength, + SafeDsaHandle key) + { + if (signatureLength > destination.Length) { - if (rgbHash == null) - throw new ArgumentNullException(nameof(rgbHash)); - if (rgbSignature == null) - throw new ArgumentNullException(nameof(rgbSignature)); + Debug.Fail($"Stack-based signDestination is insufficient ({signatureLength} needed)"); + destination = new byte[signatureLength]; + } - return VerifySignature((ReadOnlySpan)rgbHash, (ReadOnlySpan)rgbSignature); + if (!Interop.Crypto.DsaSign(key, hash, destination, out int actualLength)) + { + throw Interop.Crypto.CreateOpenSslCryptographicException(); } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS + Debug.Assert( + actualLength <= signatureLength, + "DSA_sign reported an unexpected signature size", + "DSA_sign reported signatureSize was {0}, when <= {1} was expected", + actualLength, + signatureLength); - public override bool VerifySignature(ReadOnlySpan hash, ReadOnlySpan signature) => - VerifySignatureCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation); + return destination.Slice(0, actualLength); + } - protected override bool VerifySignatureCore( - ReadOnlySpan hash, - ReadOnlySpan signature, - DSASignatureFormat signatureFormat) -#else - public override bool VerifySignature(ReadOnlySpan hash, ReadOnlySpan signature) -#endif - { - SafeDsaHandle key = GetKey(); + public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) + { + if (rgbHash == null) + throw new ArgumentNullException(nameof(rgbHash)); + if (rgbSignature == null) + throw new ArgumentNullException(nameof(rgbSignature)); + + return VerifySignature((ReadOnlySpan)rgbHash, (ReadOnlySpan)rgbSignature); + } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) - { -#endif - int expectedSignatureBytes = Interop.Crypto.DsaSignatureFieldSize(key) * 2; - if (signature.Length != expectedSignatureBytes) - { - // The input isn't of the right length (assuming no DER), so we can't sensibly re-encode it with DER. - return false; - } - - signature = AsymmetricAlgorithmHelpers.ConvertIeee1363ToDer(signature); -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - } - else if (signatureFormat != DSASignatureFormat.Rfc3279DerSequence) - { - Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); - throw new CryptographicException( - SR.Cryptography_UnknownSignatureFormat, - signatureFormat.ToString()); - } -#endif - return Interop.Crypto.DsaVerify(key, hash, signature); - } - private void ThrowIfDisposed() + public override bool VerifySignature(ReadOnlySpan hash, ReadOnlySpan signature) => + VerifySignatureCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation); + + protected override bool VerifySignatureCore( + ReadOnlySpan hash, + ReadOnlySpan signature, + DSASignatureFormat signatureFormat) + { + SafeDsaHandle key = GetKey(); + + if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { - if (_key == null) + int expectedSignatureBytes = Interop.Crypto.DsaSignatureFieldSize(key) * 2; + if (signature.Length != expectedSignatureBytes) { - throw new ObjectDisposedException( -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - nameof(DSA) -#else - nameof(DSAOpenSsl) -#endif - ); + // The input isn't of the right length (assuming no DER), so we can't sensibly re-encode it with DER. + return false; } - } - private SafeDsaHandle GetKey() + signature = AsymmetricAlgorithmHelpers.ConvertIeee1363ToDer(signature); + } + else if (signatureFormat != DSASignatureFormat.Rfc3279DerSequence) { - ThrowIfDisposed(); + Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); + throw new CryptographicException( + SR.Cryptography_UnknownSignatureFormat, + signatureFormat.ToString()); + } - SafeDsaHandle key = _key.Value; - CheckInvalidKey(key); + return Interop.Crypto.DsaVerify(key, hash, signature); + } - return key; + private void ThrowIfDisposed() + { + if (_key == null) + { + throw new ObjectDisposedException(nameof(DSAOpenSsl)); } + } - private void SetKey(SafeDsaHandle newKey) - { - // Do not call ThrowIfDisposed here, as it breaks the SafeEvpPKey ctor + private SafeDsaHandle GetKey() + { + ThrowIfDisposed(); - // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere - // with the already loaded key. - ForceSetKeySize(BitsPerByte * Interop.Crypto.DsaKeySize(newKey)); + SafeDsaHandle key = _key.Value; + CheckInvalidKey(key); - _key = new Lazy(newKey); - } + return key; + } - static partial void ThrowIfNotSupported(); + private void SetKey(SafeDsaHandle newKey) + { + // Do not call ThrowIfDisposed here, as it breaks the SafeEvpPKey ctor - private static readonly KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(minSize: 512, maxSize: 3072, skipSize: 64) }; + // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere + // with the already loaded key. + ForceSetKeySize(BitsPerByte * Interop.Crypto.DsaKeySize(newKey)); + + _key = new Lazy(newKey); } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS + + static partial void ThrowIfNotSupported(); + + private static readonly KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(minSize: 512, maxSize: 3072, skipSize: 64) }; } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSASecurityTransforms.cs b/src/libraries/Common/src/System/Security/Cryptography/DSASecurityTransforms.cs index 8b7e0dbb4ec710..a804b198d51401 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/DSASecurityTransforms.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/DSASecurityTransforms.cs @@ -1,26 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Buffers; -using System.Diagnostics; -using System.Formats.Asn1; using System.IO; -using System.Runtime.InteropServices; using System.Security.Cryptography.Apple; using Internal.Cryptography; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - public partial class DSA : AsymmetricAlgorithm - { - private static DSA CreateCore() - { - return new DSAImplementation.DSASecurityTransforms(); - } - } -#endif - internal static partial class DSAImplementation { public sealed partial class DSASecurityTransforms : DSA @@ -102,7 +88,7 @@ public override byte[] CreateSignature(byte[] rgbHash) // are always 160 bits / 20 bytes (the size of SHA-1, and the only legal length for Q). byte[] ieeeFormatSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363( derFormatSignature.AsSpan(0, derFormatSignature.Length), - fieldSizeBits: 160); + fieldSizeBits: SHA1.HashSizeInBits); return ieeeFormatSignature; } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanCng.ImportExport.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanCng.ImportExport.cs index a18e08635b9346..ebe5922994637d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanCng.ImportExport.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanCng.ImportExport.cs @@ -5,260 +5,253 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDiffieHellmanImplementation + public sealed partial class ECDiffieHellmanCng : ECDiffieHellman { -#endif - public sealed partial class ECDiffieHellmanCng : ECDiffieHellman + public override void ImportParameters(ECParameters parameters) { - public override void ImportParameters(ECParameters parameters) - { - parameters.Validate(); - ThrowIfDisposed(); + parameters.Validate(); + ThrowIfDisposed(); - ECCurve curve = parameters.Curve; - bool includePrivateParameters = parameters.D != null; - bool hasPublicParameters = parameters.Q.X != null && parameters.Q.Y != null; + ECCurve curve = parameters.Curve; + bool includePrivateParameters = parameters.D != null; + bool hasPublicParameters = parameters.Q.X != null && parameters.Q.Y != null; - if (curve.IsPrime) - { - if (!hasPublicParameters && includePrivateParameters) - { - byte[] zero = new byte[parameters.D!.Length]; - ECParameters ecParamsCopy = parameters; - ecParamsCopy.Q.X = zero; - ecParamsCopy.Q.Y = zero; - byte[] ecExplicitBlob = ECCng.GetPrimeCurveBlob(ref ecParamsCopy, ecdh: true); - ImportFullKeyBlob(ecExplicitBlob, includePrivateParameters: true); - } - else - { - byte[] ecExplicitBlob = ECCng.GetPrimeCurveBlob(ref parameters, ecdh: true); - ImportFullKeyBlob(ecExplicitBlob, includePrivateParameters); - } - } - else if (curve.IsNamed) + if (curve.IsPrime) + { + if (!hasPublicParameters && includePrivateParameters) { - // FriendlyName is required; an attempt was already made to default it in ECCurve - if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) - { - throw new PlatformNotSupportedException( - SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value)); - } - - if (!hasPublicParameters && includePrivateParameters) - { - byte[] zero = new byte[parameters.D!.Length]; - ECParameters ecParamsCopy = parameters; - ecParamsCopy.Q.X = zero; - ecParamsCopy.Q.Y = zero; - byte[] ecNamedCurveBlob = ECCng.GetNamedCurveBlob(ref ecParamsCopy, ecdh: true); - ImportKeyBlob(ecNamedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters: true); - } - else - { - byte[] ecNamedCurveBlob = ECCng.GetNamedCurveBlob(ref parameters, ecdh: true); - ImportKeyBlob(ecNamedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters); - } + byte[] zero = new byte[parameters.D!.Length]; + ECParameters ecParamsCopy = parameters; + ecParamsCopy.Q.X = zero; + ecParamsCopy.Q.Y = zero; + byte[] ecExplicitBlob = ECCng.GetPrimeCurveBlob(ref ecParamsCopy, ecdh: true); + ImportFullKeyBlob(ecExplicitBlob, includePrivateParameters: true); } else { - throw new PlatformNotSupportedException( - SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); + byte[] ecExplicitBlob = ECCng.GetPrimeCurveBlob(ref parameters, ecdh: true); + ImportFullKeyBlob(ecExplicitBlob, includePrivateParameters); } } - - public override ECParameters ExportExplicitParameters(bool includePrivateParameters) + else if (curve.IsNamed) { - byte[] blob = ExportFullKeyBlob(includePrivateParameters); + // FriendlyName is required; an attempt was already made to default it in ECCurve + if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) + { + throw new PlatformNotSupportedException( + SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value)); + } - try + if (!hasPublicParameters && includePrivateParameters) { - ECParameters ecparams = default; - ECCng.ExportPrimeCurveParameters(ref ecparams, blob, includePrivateParameters); - return ecparams; + byte[] zero = new byte[parameters.D!.Length]; + ECParameters ecParamsCopy = parameters; + ecParamsCopy.Q.X = zero; + ecParamsCopy.Q.Y = zero; + byte[] ecNamedCurveBlob = ECCng.GetNamedCurveBlob(ref ecParamsCopy, ecdh: true); + ImportKeyBlob(ecNamedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters: true); } - finally + else { - Array.Clear(blob); + byte[] ecNamedCurveBlob = ECCng.GetNamedCurveBlob(ref parameters, ecdh: true); + ImportKeyBlob(ecNamedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters); } } + else + { + throw new PlatformNotSupportedException( + SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); + } + } - public override ECParameters ExportParameters(bool includePrivateParameters) + public override ECParameters ExportExplicitParameters(bool includePrivateParameters) + { + byte[] blob = ExportFullKeyBlob(includePrivateParameters); + + try { ECParameters ecparams = default; + ECCng.ExportPrimeCurveParameters(ref ecparams, blob, includePrivateParameters); + return ecparams; + } + finally + { + Array.Clear(blob); + } + } - string? curveName = GetCurveName(out string? oidValue); - byte[]? blob = null; + public override ECParameters ExportParameters(bool includePrivateParameters) + { + ECParameters ecparams = default; - try + string? curveName = GetCurveName(out string? oidValue); + byte[]? blob = null; + + try + { + if (string.IsNullOrEmpty(curveName)) { - if (string.IsNullOrEmpty(curveName)) - { - blob = ExportFullKeyBlob(includePrivateParameters); - ECCng.ExportPrimeCurveParameters(ref ecparams, blob, includePrivateParameters); - } - else - { - blob = ExportKeyBlob(includePrivateParameters); - ECCng.ExportNamedCurveParameters(ref ecparams, blob, includePrivateParameters); - ecparams.Curve = ECCurve.CreateFromOid(new Oid(oidValue, curveName)); - } - - return ecparams; + blob = ExportFullKeyBlob(includePrivateParameters); + ECCng.ExportPrimeCurveParameters(ref ecparams, blob, includePrivateParameters); } - finally + else { - if (blob != null) - { - Array.Clear(blob); - } + blob = ExportKeyBlob(includePrivateParameters); + ECCng.ExportNamedCurveParameters(ref ecparams, blob, includePrivateParameters); + ecparams.Curve = ECCurve.CreateFromOid(new Oid(oidValue, curveName)); } - } - - public override void ImportPkcs8PrivateKey(ReadOnlySpan source, out int bytesRead) - { - ThrowIfDisposed(); - CngPkcs8.Pkcs8Response response = CngPkcs8.ImportPkcs8PrivateKey(source, out int localRead); - ProcessPkcs8Response(response); - bytesRead = localRead; + return ecparams; } - - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - ReadOnlySpan source, - out int bytesRead) + finally { - ThrowIfDisposed(); - CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey( - passwordBytes, - source, - out int localRead); - - ProcessPkcs8Response(response); - bytesRead = localRead; + if (blob != null) + { + Array.Clear(blob); + } } + } - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - ReadOnlySpan source, - out int bytesRead) - { - ThrowIfDisposed(); - CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey( - password, - source, - out int localRead); + public override void ImportPkcs8PrivateKey(ReadOnlySpan source, out int bytesRead) + { + ThrowIfDisposed(); + CngPkcs8.Pkcs8Response response = CngPkcs8.ImportPkcs8PrivateKey(source, out int localRead); - ProcessPkcs8Response(response); - bytesRead = localRead; - } + ProcessPkcs8Response(response); + bytesRead = localRead; + } - private void ProcessPkcs8Response(CngPkcs8.Pkcs8Response response) - { - // Wrong algorithm? - if (response.GetAlgorithmGroup() != BCryptNative.AlgorithmName.ECDH) - { - response.FreeKey(); - throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); - } + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey( + passwordBytes, + source, + out int localRead); + + ProcessPkcs8Response(response); + bytesRead = localRead; + } - AcceptImport(response); - } + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey( + password, + source, + out int localRead); + + ProcessPkcs8Response(response); + bytesRead = localRead; + } - public override byte[] ExportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - PbeParameters pbeParameters) + private void ProcessPkcs8Response(CngPkcs8.Pkcs8Response response) + { + // Wrong algorithm? + if (response.GetAlgorithmGroup() != BCryptNative.AlgorithmName.ECDH) { - if (pbeParameters == null) - throw new ArgumentNullException(nameof(pbeParameters)); - - return CngPkcs8.ExportEncryptedPkcs8PrivateKey( - this, - passwordBytes, - pbeParameters); + response.FreeKey(); + throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); } - public override byte[] ExportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - PbeParameters pbeParameters) - { - if (pbeParameters == null) - { - throw new ArgumentNullException(nameof(pbeParameters)); - } + AcceptImport(response); + } - PasswordBasedEncryption.ValidatePbeParameters( - pbeParameters, - password, - ReadOnlySpan.Empty); + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters) + { + if (pbeParameters == null) + throw new ArgumentNullException(nameof(pbeParameters)); - if (CngPkcs8.IsPlatformScheme(pbeParameters)) - { - return ExportEncryptedPkcs8(password, pbeParameters.IterationCount); - } + return CngPkcs8.ExportEncryptedPkcs8PrivateKey( + this, + passwordBytes, + pbeParameters); + } - return CngPkcs8.ExportEncryptedPkcs8PrivateKey( - this, - password, - pbeParameters); + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters) + { + if (pbeParameters == null) + { + throw new ArgumentNullException(nameof(pbeParameters)); } - public override bool TryExportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - PbeParameters pbeParameters, - Span destination, - out int bytesWritten) + PasswordBasedEncryption.ValidatePbeParameters( + pbeParameters, + password, + ReadOnlySpan.Empty); + + if (CngPkcs8.IsPlatformScheme(pbeParameters)) { - if (pbeParameters == null) - throw new ArgumentNullException(nameof(pbeParameters)); - - PasswordBasedEncryption.ValidatePbeParameters( - pbeParameters, - ReadOnlySpan.Empty, - passwordBytes); - - return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( - this, - passwordBytes, - pbeParameters, - destination, - out bytesWritten); + return ExportEncryptedPkcs8(password, pbeParameters.IterationCount); } - public override bool TryExportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - PbeParameters pbeParameters, - Span destination, - out int bytesWritten) - { - if (pbeParameters == null) - throw new ArgumentNullException(nameof(pbeParameters)); + return CngPkcs8.ExportEncryptedPkcs8PrivateKey( + this, + password, + pbeParameters); + } - PasswordBasedEncryption.ValidatePbeParameters( - pbeParameters, - password, - ReadOnlySpan.Empty); + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) + { + if (pbeParameters == null) + throw new ArgumentNullException(nameof(pbeParameters)); + + PasswordBasedEncryption.ValidatePbeParameters( + pbeParameters, + ReadOnlySpan.Empty, + passwordBytes); + + return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( + this, + passwordBytes, + pbeParameters, + destination, + out bytesWritten); + } - if (CngPkcs8.IsPlatformScheme(pbeParameters)) - { - return TryExportEncryptedPkcs8( - password, - pbeParameters.IterationCount, - destination, - out bytesWritten); - } + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) + { + if (pbeParameters == null) + throw new ArgumentNullException(nameof(pbeParameters)); + + PasswordBasedEncryption.ValidatePbeParameters( + pbeParameters, + password, + ReadOnlySpan.Empty); - return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( - this, + if (CngPkcs8.IsPlatformScheme(pbeParameters)) + { + return TryExportEncryptedPkcs8( password, - pbeParameters, + pbeParameters.IterationCount, destination, out bytesWritten); } + + return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( + this, + password, + pbeParameters, + destination, + out bytesWritten); } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanCng.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanCng.cs index ad955d55ce8eed..f1db21ff401e77 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanCng.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanCng.cs @@ -1,141 +1,138 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDiffieHellmanImplementation + public sealed partial class ECDiffieHellmanCng : ECDiffieHellman { -#endif - public sealed partial class ECDiffieHellmanCng : ECDiffieHellman + [SupportedOSPlatform("windows")] + public ECDiffieHellmanCng() : this(521) { } + + [SupportedOSPlatform("windows")] + public ECDiffieHellmanCng(int keySize) { - public ECDiffieHellmanCng() : this(521) { } + KeySize = keySize; + } - public ECDiffieHellmanCng(int keySize) - { - KeySize = keySize; - } + [SupportedOSPlatform("windows")] + public ECDiffieHellmanCng(ECCurve curve) + { + // GenerateKey will already do all of the validation we need. + GenerateKey(curve); + } - public ECDiffieHellmanCng(ECCurve curve) + public override int KeySize + { + get { - // GenerateKey will already do all of the validation we need. - GenerateKey(curve); + return base.KeySize; } - - public override int KeySize + set { - get + if (KeySize == value) { - return base.KeySize; + return; } - set - { - if (KeySize == value) - { - return; - } - // Set the KeySize before DisposeKey so that an invalid value doesn't throw away the key - base.KeySize = value; + // Set the KeySize before DisposeKey so that an invalid value doesn't throw away the key + base.KeySize = value; - DisposeKey(); - // Key will be lazily re-created - } + DisposeKey(); + // Key will be lazily re-created } + } - /// - /// Set the KeySize without validating against LegalKeySizes. - /// - /// The value to set the KeySize to. - private void ForceSetKeySize(int newKeySize) - { - // In the event that a key was loaded via ImportParameters, curve name, or an IntPtr/SafeHandle - // it could be outside of the bounds that we currently represent as "legal key sizes". - // Since that is our view into the underlying component it can be detached from the - // component's understanding. If it said it has opened a key, and this is the size, trust it. - KeySizeValue = newKeySize; - } + /// + /// Set the KeySize without validating against LegalKeySizes. + /// + /// The value to set the KeySize to. + private void ForceSetKeySize(int newKeySize) + { + // In the event that a key was loaded via ImportParameters, curve name, or an IntPtr/SafeHandle + // it could be outside of the bounds that we currently represent as "legal key sizes". + // Since that is our view into the underlying component it can be detached from the + // component's understanding. If it said it has opened a key, and this is the size, trust it. + KeySizeValue = newKeySize; + } - public override KeySizes[] LegalKeySizes + public override KeySizes[] LegalKeySizes + { + get { - get - { - // Return the three sizes that can be explicitly set (for backwards compatibility) - return new[] { - new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), - new KeySizes(minSize: 521, maxSize: 521, skipSize: 0), - }; - } + // Return the three sizes that can be explicitly set (for backwards compatibility) + return new[] { + new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), + new KeySizes(minSize: 521, maxSize: 521, skipSize: 0), + }; } + } - public override byte[] DeriveKeyFromHash( - ECDiffieHellmanPublicKey otherPartyPublicKey, - HashAlgorithmName hashAlgorithm, - byte[]? secretPrepend, - byte[]? secretAppend) - { - ArgumentNullException.ThrowIfNull(otherPartyPublicKey); - ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); + public override byte[] DeriveKeyFromHash( + ECDiffieHellmanPublicKey otherPartyPublicKey, + HashAlgorithmName hashAlgorithm, + byte[]? secretPrepend, + byte[]? secretAppend) + { + ArgumentNullException.ThrowIfNull(otherPartyPublicKey); + ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); - using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey)) - { - return Interop.NCrypt.DeriveKeyMaterialHash( - secretAgreement, - hashAlgorithm.Name, - secretPrepend, - secretAppend, - Interop.NCrypt.SecretAgreementFlags.None); - } + using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey)) + { + return Interop.NCrypt.DeriveKeyMaterialHash( + secretAgreement, + hashAlgorithm.Name, + secretPrepend, + secretAppend, + Interop.NCrypt.SecretAgreementFlags.None); } + } - public override byte[] DeriveKeyFromHmac( - ECDiffieHellmanPublicKey otherPartyPublicKey, - HashAlgorithmName hashAlgorithm, - byte[]? hmacKey, - byte[]? secretPrepend, - byte[]? secretAppend) - { - ArgumentNullException.ThrowIfNull(otherPartyPublicKey); - ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); + public override byte[] DeriveKeyFromHmac( + ECDiffieHellmanPublicKey otherPartyPublicKey, + HashAlgorithmName hashAlgorithm, + byte[]? hmacKey, + byte[]? secretPrepend, + byte[]? secretAppend) + { + ArgumentNullException.ThrowIfNull(otherPartyPublicKey); + ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); - using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey)) - { - Interop.NCrypt.SecretAgreementFlags flags = hmacKey == null ? - Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey : - Interop.NCrypt.SecretAgreementFlags.None; - - return Interop.NCrypt.DeriveKeyMaterialHmac( - secretAgreement, - hashAlgorithm.Name, - hmacKey, - secretPrepend, - secretAppend, - flags); - } + using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey)) + { + Interop.NCrypt.SecretAgreementFlags flags = hmacKey == null ? + Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey : + Interop.NCrypt.SecretAgreementFlags.None; + + return Interop.NCrypt.DeriveKeyMaterialHmac( + secretAgreement, + hashAlgorithm.Name, + hmacKey, + secretPrepend, + secretAppend, + flags); } + } - public override byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed) + public override byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed) + { + if (otherPartyPublicKey == null) + throw new ArgumentNullException(nameof(otherPartyPublicKey)); + if (prfLabel == null) + throw new ArgumentNullException(nameof(prfLabel)); + if (prfSeed == null) + throw new ArgumentNullException(nameof(prfSeed)); + + using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey)) { - if (otherPartyPublicKey == null) - throw new ArgumentNullException(nameof(otherPartyPublicKey)); - if (prfLabel == null) - throw new ArgumentNullException(nameof(prfLabel)); - if (prfSeed == null) - throw new ArgumentNullException(nameof(prfSeed)); - - using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey)) - { - return Interop.NCrypt.DeriveKeyMaterialTls( - secretAgreement, - prfLabel, - prfSeed, - Interop.NCrypt.SecretAgreementFlags.None); - } + return Interop.NCrypt.DeriveKeyMaterialTls( + secretAgreement, + prfLabel, + prfSeed, + Interop.NCrypt.SecretAgreementFlags.None); } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.Derive.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.Derive.cs index 9d32a702bf07fa..bee07782afc3d9 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.Derive.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.Derive.cs @@ -6,196 +6,189 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDiffieHellmanImplementation + public sealed partial class ECDiffieHellmanOpenSsl : ECDiffieHellman { -#endif - public sealed partial class ECDiffieHellmanOpenSsl : ECDiffieHellman + /// + /// Given a second party's public key, derive shared key material + /// + public override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey) => + DeriveKeyFromHash(otherPartyPublicKey, HashAlgorithmName.SHA256, null, null); + + public override byte[] DeriveKeyFromHash( + ECDiffieHellmanPublicKey otherPartyPublicKey, + HashAlgorithmName hashAlgorithm, + byte[]? secretPrepend, + byte[]? secretAppend) { - /// - /// Given a second party's public key, derive shared key material - /// - public override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey) => - DeriveKeyFromHash(otherPartyPublicKey, HashAlgorithmName.SHA256, null, null); - - public override byte[] DeriveKeyFromHash( - ECDiffieHellmanPublicKey otherPartyPublicKey, - HashAlgorithmName hashAlgorithm, - byte[]? secretPrepend, - byte[]? secretAppend) - { - ArgumentNullException.ThrowIfNull(otherPartyPublicKey); - ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); + ArgumentNullException.ThrowIfNull(otherPartyPublicKey); + ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); - ThrowIfDisposed(); + ThrowIfDisposed(); - return ECDiffieHellmanDerivation.DeriveKeyFromHash( - otherPartyPublicKey, - hashAlgorithm, - secretPrepend, - secretAppend, - (pubKey, hasher) => DeriveSecretAgreement(pubKey, hasher)); - } + return ECDiffieHellmanDerivation.DeriveKeyFromHash( + otherPartyPublicKey, + hashAlgorithm, + secretPrepend, + secretAppend, + (pubKey, hasher) => DeriveSecretAgreement(pubKey, hasher)); + } - public override byte[] DeriveKeyFromHmac( - ECDiffieHellmanPublicKey otherPartyPublicKey, - HashAlgorithmName hashAlgorithm, - byte[]? hmacKey, - byte[]? secretPrepend, - byte[]? secretAppend) - { - ArgumentNullException.ThrowIfNull(otherPartyPublicKey); - ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); - - ThrowIfDisposed(); - - return ECDiffieHellmanDerivation.DeriveKeyFromHmac( - otherPartyPublicKey, - hashAlgorithm, - hmacKey, - secretPrepend, - secretAppend, - (pubKey, hasher) => DeriveSecretAgreement(pubKey, hasher)); - } + public override byte[] DeriveKeyFromHmac( + ECDiffieHellmanPublicKey otherPartyPublicKey, + HashAlgorithmName hashAlgorithm, + byte[]? hmacKey, + byte[]? secretPrepend, + byte[]? secretAppend) + { + ArgumentNullException.ThrowIfNull(otherPartyPublicKey); + ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); + + ThrowIfDisposed(); + + return ECDiffieHellmanDerivation.DeriveKeyFromHmac( + otherPartyPublicKey, + hashAlgorithm, + hmacKey, + secretPrepend, + secretAppend, + (pubKey, hasher) => DeriveSecretAgreement(pubKey, hasher)); + } - public override byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed) - { - if (otherPartyPublicKey == null) - throw new ArgumentNullException(nameof(otherPartyPublicKey)); - if (prfLabel == null) - throw new ArgumentNullException(nameof(prfLabel)); - if (prfSeed == null) - throw new ArgumentNullException(nameof(prfSeed)); - - ThrowIfDisposed(); - - return ECDiffieHellmanDerivation.DeriveKeyTls( - otherPartyPublicKey, - prfLabel, - prfSeed, - (pubKey, hasher) => DeriveSecretAgreement(pubKey, hasher)); - } + public override byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed) + { + if (otherPartyPublicKey == null) + throw new ArgumentNullException(nameof(otherPartyPublicKey)); + if (prfLabel == null) + throw new ArgumentNullException(nameof(prfLabel)); + if (prfSeed == null) + throw new ArgumentNullException(nameof(prfSeed)); + + ThrowIfDisposed(); + + return ECDiffieHellmanDerivation.DeriveKeyTls( + otherPartyPublicKey, + prfLabel, + prfSeed, + (pubKey, hasher) => DeriveSecretAgreement(pubKey, hasher)); + } + + /// + /// Get the secret agreement generated between two parties + /// + private byte[]? DeriveSecretAgreement(ECDiffieHellmanPublicKey otherPartyPublicKey, IncrementalHash? hasher) + { + Debug.Assert(otherPartyPublicKey != null); - /// - /// Get the secret agreement generated between two parties - /// - private byte[]? DeriveSecretAgreement(ECDiffieHellmanPublicKey otherPartyPublicKey, IncrementalHash? hasher) + // Ensure that this ECDH object contains a private key by attempting a parameter export + // which will throw an OpenSslCryptoException if no private key is available + ECParameters thisKeyExplicit = ExportExplicitParameters(true); + bool thisIsNamed = Interop.Crypto.EcKeyHasCurveName(_key.Value); + ECDiffieHellmanOpenSslPublicKey? otherKey = otherPartyPublicKey as ECDiffieHellmanOpenSslPublicKey; + bool disposeOtherKey = false; + + if (otherKey == null) { - Debug.Assert(otherPartyPublicKey != null); + disposeOtherKey = true; - // Ensure that this ECDH object contains a private key by attempting a parameter export - // which will throw an OpenSslCryptoException if no private key is available - ECParameters thisKeyExplicit = ExportExplicitParameters(true); - bool thisIsNamed = Interop.Crypto.EcKeyHasCurveName(_key.Value); - ECDiffieHellmanOpenSslPublicKey? otherKey = otherPartyPublicKey as ECDiffieHellmanOpenSslPublicKey; - bool disposeOtherKey = false; + ECParameters otherParameters = + thisIsNamed + ? otherPartyPublicKey.ExportParameters() + : otherPartyPublicKey.ExportExplicitParameters(); - if (otherKey == null) - { - disposeOtherKey = true; + otherKey = new ECDiffieHellmanOpenSslPublicKey(otherParameters); + } - ECParameters otherParameters = - thisIsNamed - ? otherPartyPublicKey.ExportParameters() - : otherPartyPublicKey.ExportExplicitParameters(); + bool otherIsNamed = otherKey.HasCurveName; - otherKey = new ECDiffieHellmanOpenSslPublicKey(otherParameters); - } + SafeEvpPKeyHandle? ourKey = null; + SafeEvpPKeyHandle? theirKey = null; + byte[]? rented = null; + int secretLength = 0; - bool otherIsNamed = otherKey.HasCurveName; + try + { + if (otherKey.KeySize != KeySize) + { + throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey)); + } - SafeEvpPKeyHandle? ourKey = null; - SafeEvpPKeyHandle? theirKey = null; - byte[]? rented = null; - int secretLength = 0; + if (otherIsNamed == thisIsNamed) + { + ourKey = _key.UpRefKeyHandle(); + theirKey = otherKey.DuplicateKeyHandle(); + } + else if (otherIsNamed) + { + ourKey = _key.UpRefKeyHandle(); - try + using (ECOpenSsl tmp = new ECOpenSsl(otherKey.ExportExplicitParameters())) + { + theirKey = tmp.UpRefKeyHandle(); + } + } + else { - if (otherKey.KeySize != KeySize) + using (ECOpenSsl tmp = new ECOpenSsl(thisKeyExplicit)) { - throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey)); + ourKey = tmp.UpRefKeyHandle(); } - if (otherIsNamed == thisIsNamed) + theirKey = otherKey.DuplicateKeyHandle(); + } + + using (SafeEvpPKeyCtxHandle ctx = Interop.Crypto.EvpPKeyCtxCreate(ourKey, theirKey, out uint secretLengthU)) + { + if (ctx == null || ctx.IsInvalid || secretLengthU == 0 || secretLengthU > int.MaxValue) { - ourKey = _key.UpRefKeyHandle(); - theirKey = otherKey.DuplicateKeyHandle(); + throw Interop.Crypto.CreateOpenSslCryptographicException(); } - else if (otherIsNamed) - { - ourKey = _key.UpRefKeyHandle(); - using (ECOpenSsl tmp = new ECOpenSsl(otherKey.ExportExplicitParameters())) - { - theirKey = tmp.UpRefKeyHandle(); - } + secretLength = (int)secretLengthU; + + // Indicate that secret can hold stackallocs from nested scopes + Span secret = stackalloc byte[0]; + + // Arbitrary limit. But it covers secp521r1, which is the biggest common case. + const int StackAllocMax = 66; + + if (secretLength > StackAllocMax) + { + rented = CryptoPool.Rent(secretLength); + secret = new Span(rented, 0, secretLength); } else { - using (ECOpenSsl tmp = new ECOpenSsl(thisKeyExplicit)) - { - ourKey = tmp.UpRefKeyHandle(); - } - - theirKey = otherKey.DuplicateKeyHandle(); + secret = stackalloc byte[secretLength]; } - using (SafeEvpPKeyCtxHandle ctx = Interop.Crypto.EvpPKeyCtxCreate(ourKey, theirKey, out uint secretLengthU)) - { - if (ctx == null || ctx.IsInvalid || secretLengthU == 0 || secretLengthU > int.MaxValue) - { - throw Interop.Crypto.CreateOpenSslCryptographicException(); - } - - secretLength = (int)secretLengthU; - - // Indicate that secret can hold stackallocs from nested scopes - Span secret = stackalloc byte[0]; - - // Arbitrary limit. But it covers secp521r1, which is the biggest common case. - const int StackAllocMax = 66; - - if (secretLength > StackAllocMax) - { - rented = CryptoPool.Rent(secretLength); - secret = new Span(rented, 0, secretLength); - } - else - { - secret = stackalloc byte[secretLength]; - } - - Interop.Crypto.EvpPKeyDeriveSecretAgreement(ctx, secret); - - if (hasher == null) - { - return secret.ToArray(); - } - else - { - hasher.AppendData(secret); - return null; - } - } - } - finally - { - theirKey?.Dispose(); - ourKey?.Dispose(); + Interop.Crypto.EvpPKeyDeriveSecretAgreement(ctx, secret); - if (disposeOtherKey) + if (hasher == null) { - otherKey.Dispose(); + return secret.ToArray(); } - - if (rented != null) + else { - CryptoPool.Return(rented, secretLength); + hasher.AppendData(secret); + return null; } } } + finally + { + theirKey?.Dispose(); + ourKey?.Dispose(); + + if (disposeOtherKey) + { + otherKey.Dispose(); + } + + if (rented != null) + { + CryptoPool.Return(rented, secretLength); + } + } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs index d1fa05f1db39c2..29a082879de227 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs @@ -1,144 +1,147 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDiffieHellmanImplementation + public sealed partial class ECDiffieHellmanOpenSsl : ECDiffieHellman { -#endif - public sealed partial class ECDiffieHellmanOpenSsl : ECDiffieHellman + private ECOpenSsl _key; + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDiffieHellmanOpenSsl(ECCurve curve) { - private ECOpenSsl _key; + ThrowIfNotSupported(); + _key = new ECOpenSsl(curve); + KeySizeValue = _key.KeySize; + } - public ECDiffieHellmanOpenSsl(ECCurve curve) - { - ThrowIfNotSupported(); - _key = new ECOpenSsl(curve); - KeySizeValue = _key.KeySize; - } + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDiffieHellmanOpenSsl() + : this(521) + { + } - public ECDiffieHellmanOpenSsl() - : this(521) - { - } + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDiffieHellmanOpenSsl(int keySize) + { + ThrowIfNotSupported(); + base.KeySize = keySize; + _key = new ECOpenSsl(this); + } - public ECDiffieHellmanOpenSsl(int keySize) + public override KeySizes[] LegalKeySizes => + new[] { + new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), + new KeySizes(minSize: 521, maxSize: 521, skipSize: 0) + }; + + protected override void Dispose(bool disposing) + { + if (disposing) { - ThrowIfNotSupported(); - base.KeySize = keySize; - _key = new ECOpenSsl(this); + _key?.Dispose(); + _key = null!; } - public override KeySizes[] LegalKeySizes => - new[] { - new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), - new KeySizes(minSize: 521, maxSize: 521, skipSize: 0) - }; + base.Dispose(disposing); + } - protected override void Dispose(bool disposing) + public override int KeySize + { + get { - if (disposing) - { - _key?.Dispose(); - _key = null!; - } - - base.Dispose(disposing); + return base.KeySize; } - - public override int KeySize + set { - get + if (KeySize == value) { - return base.KeySize; + return; } - set - { - if (KeySize == value) - { - return; - } - // Set the KeySize before FreeKey so that an invalid value doesn't throw away the key - base.KeySize = value; + // Set the KeySize before FreeKey so that an invalid value doesn't throw away the key + base.KeySize = value; - ThrowIfDisposed(); - _key.Dispose(); - _key = new ECOpenSsl(this); - } - } - - public override void GenerateKey(ECCurve curve) - { ThrowIfDisposed(); - KeySizeValue = _key.GenerateKey(curve); + _key.Dispose(); + _key = new ECOpenSsl(this); } + } - public override ECDiffieHellmanPublicKey PublicKey - { - get - { - ThrowIfDisposed(); - return new ECDiffieHellmanOpenSslPublicKey(_key.UpRefKeyHandle()); - } - } + public override void GenerateKey(ECCurve curve) + { + ThrowIfDisposed(); + KeySizeValue = _key.GenerateKey(curve); + } - public override void ImportParameters(ECParameters parameters) + public override ECDiffieHellmanPublicKey PublicKey + { + get { ThrowIfDisposed(); - KeySizeValue = _key.ImportParameters(parameters); + return new ECDiffieHellmanOpenSslPublicKey(_key.UpRefKeyHandle()); } + } - public override ECParameters ExportExplicitParameters(bool includePrivateParameters) => - ECOpenSsl.ExportExplicitParameters(GetKey(), includePrivateParameters); + public override void ImportParameters(ECParameters parameters) + { + ThrowIfDisposed(); + KeySizeValue = _key.ImportParameters(parameters); + } - public override ECParameters ExportParameters(bool includePrivateParameters) => - ECOpenSsl.ExportParameters(GetKey(), includePrivateParameters); + public override ECParameters ExportExplicitParameters(bool includePrivateParameters) => + ECOpenSsl.ExportExplicitParameters(GetKey(), includePrivateParameters); - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - ReadOnlySpan source, - out int bytesRead) - { - ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); - } + public override ECParameters ExportParameters(bool includePrivateParameters) => + ECOpenSsl.ExportParameters(GetKey(), includePrivateParameters); - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - ReadOnlySpan source, - out int bytesRead) - { - ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); - } + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + } - private void ThrowIfDisposed() - { - if (_key == null) - { - throw new ObjectDisposedException( -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - nameof(ECDiffieHellman) -#else - nameof(ECDiffieHellmanOpenSsl) -#endif - ); - } - } + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + } - private SafeEcKeyHandle GetKey() + private void ThrowIfDisposed() + { + if (_key == null) { - ThrowIfDisposed(); - return _key.Value; + throw new ObjectDisposedException(nameof(ECDiffieHellmanOpenSsl)); } + } - static partial void ThrowIfNotSupported(); + private SafeEcKeyHandle GetKey() + { + ThrowIfDisposed(); + return _key.Value; } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS + + static partial void ThrowIfNotSupported(); } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSslPublicKey.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSslPublicKey.cs index 00dde9c3b1bf2e..d36370d054f9a0 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSslPublicKey.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanOpenSslPublicKey.cs @@ -5,121 +5,108 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDiffieHellmanImplementation + internal sealed class ECDiffieHellmanOpenSslPublicKey : ECDiffieHellmanPublicKey { -#endif - internal sealed class ECDiffieHellmanOpenSslPublicKey : ECDiffieHellmanPublicKey + private ECOpenSsl _key; + + internal ECDiffieHellmanOpenSslPublicKey(SafeEvpPKeyHandle pkeyHandle) { - private ECOpenSsl _key; + if (pkeyHandle == null) + throw new ArgumentNullException(nameof(pkeyHandle)); + if (pkeyHandle.IsInvalid) + throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle)); + + // If ecKey is valid it has already been up-ref'd, so we can just use this handle as-is. + SafeEcKeyHandle key = Interop.Crypto.EvpPkeyGetEcKey(pkeyHandle); - internal ECDiffieHellmanOpenSslPublicKey(SafeEvpPKeyHandle pkeyHandle) + if (key.IsInvalid) { - if (pkeyHandle == null) - throw new ArgumentNullException(nameof(pkeyHandle)); - if (pkeyHandle.IsInvalid) - throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle)); + key.Dispose(); + throw Interop.Crypto.CreateOpenSslCryptographicException(); + } - // If ecKey is valid it has already been up-ref'd, so we can just use this handle as-is. - SafeEcKeyHandle key = Interop.Crypto.EvpPkeyGetEcKey(pkeyHandle); + _key = new ECOpenSsl(key); + } - if (key.IsInvalid) - { - key.Dispose(); - throw Interop.Crypto.CreateOpenSslCryptographicException(); - } + internal ECDiffieHellmanOpenSslPublicKey(ECParameters parameters) + { + _key = new ECOpenSsl(parameters); + } - _key = new ECOpenSsl(key); - } + public override string ToXmlString() + { + throw new PlatformNotSupportedException(); + } - internal ECDiffieHellmanOpenSslPublicKey(ECParameters parameters) - { - _key = new ECOpenSsl(parameters); - } + public override byte[] ToByteArray() + { + throw new PlatformNotSupportedException(); + } + + public override ECParameters ExportExplicitParameters() => + ECOpenSsl.ExportExplicitParameters(GetKey(), includePrivateParameters: false); + + public override ECParameters ExportParameters() => + ECOpenSsl.ExportParameters(GetKey(), includePrivateParameters: false); - public override string ToXmlString() + internal bool HasCurveName => Interop.Crypto.EcKeyHasCurveName(GetKey()); + + internal int KeySize + { + get { - throw new PlatformNotSupportedException(); + ThrowIfDisposed(); + return _key.KeySize; } + } - public override byte[] ToByteArray() + protected override void Dispose(bool disposing) + { + if (disposing) { - throw new PlatformNotSupportedException(); + _key?.Dispose(); + _key = null!; } - public override ECParameters ExportExplicitParameters() => - ECOpenSsl.ExportExplicitParameters(GetKey(), includePrivateParameters: false); - - public override ECParameters ExportParameters() => - ECOpenSsl.ExportParameters(GetKey(), includePrivateParameters: false); - - internal bool HasCurveName => Interop.Crypto.EcKeyHasCurveName(GetKey()); + base.Dispose(disposing); + } - internal int KeySize - { - get - { - ThrowIfDisposed(); - return _key.KeySize; - } - } + internal SafeEvpPKeyHandle DuplicateKeyHandle() + { + SafeEcKeyHandle currentKey = GetKey(); + SafeEvpPKeyHandle pkeyHandle = Interop.Crypto.EvpPkeyCreate(); - protected override void Dispose(bool disposing) + try { - if (disposing) + // Wrapping our key in an EVP_PKEY will up_ref our key. + // When the EVP_PKEY is Disposed it will down_ref the key. + // So everything should be copacetic. + if (!Interop.Crypto.EvpPkeySetEcKey(pkeyHandle, currentKey)) { - _key?.Dispose(); - _key = null!; + throw Interop.Crypto.CreateOpenSslCryptographicException(); } - base.Dispose(disposing); + return pkeyHandle; } - - internal SafeEvpPKeyHandle DuplicateKeyHandle() + catch { - SafeEcKeyHandle currentKey = GetKey(); - SafeEvpPKeyHandle pkeyHandle = Interop.Crypto.EvpPkeyCreate(); - - try - { - // Wrapping our key in an EVP_PKEY will up_ref our key. - // When the EVP_PKEY is Disposed it will down_ref the key. - // So everything should be copacetic. - if (!Interop.Crypto.EvpPkeySetEcKey(pkeyHandle, currentKey)) - { - throw Interop.Crypto.CreateOpenSslCryptographicException(); - } - - return pkeyHandle; - } - catch - { - pkeyHandle.Dispose(); - throw; - } + pkeyHandle.Dispose(); + throw; } + } - private void ThrowIfDisposed() + private void ThrowIfDisposed() + { + if (_key == null) { - if (_key == null) - { - throw new ObjectDisposedException( -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - nameof(ECDiffieHellmanPublicKey) -#else - nameof(ECDiffieHellmanOpenSslPublicKey) -#endif - ); - } + throw new ObjectDisposedException(nameof(ECDiffieHellmanOpenSslPublicKey)); } + } - private SafeEcKeyHandle GetKey() - { - ThrowIfDisposed(); - return _key.Value; - } + private SafeEcKeyHandle GetKey() + { + ThrowIfDisposed(); + return _key.Value; } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanSecurityTransforms.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanSecurityTransforms.cs index df1a7fae8e39a0..ff17de4523cde4 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanSecurityTransforms.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDiffieHellmanSecurityTransforms.cs @@ -79,6 +79,11 @@ public override ECParameters ExportParameters(bool includePrivateParameters) return _ecc.ExportParameters(includePrivateParameters, KeySize); } + internal bool TryExportDataKeyParameters(bool includePrivateParameters, ref ECParameters ecParameters) + { + return _ecc.TryExportDataKeyParameters(includePrivateParameters, KeySize, ref ecParameters); + } + public override void ImportParameters(ECParameters parameters) { KeySizeValue = _ecc.ImportParameters(parameters); diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.HashData.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.HashData.cs index 77334289583966..fcbc2db36376e2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.HashData.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.HashData.cs @@ -1,18 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Diagnostics; using System.IO; using Internal.Cryptography; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDsaImplementation - { -#endif public sealed partial class ECDsaCng : ECDsa { protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => @@ -24,7 +18,4 @@ protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) protected override bool TryHashData(ReadOnlySpan source, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) => CngCommon.TryHashData(source, destination, hashAlgorithm, out bytesWritten); } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.ImportExport.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.ImportExport.cs index f37c712f70daf4..003c6ba312f40a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.ImportExport.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.ImportExport.cs @@ -5,277 +5,270 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDsaImplementation + public sealed partial class ECDsaCng : ECDsa { -#endif - public sealed partial class ECDsaCng : ECDsa + /// + /// ImportParameters will replace the existing key that ECDsaCng is working with by creating a + /// new CngKey. If the parameters contains only Q, then only a public key will be imported. + /// If the parameters also contains D, then a full key pair will be imported. + /// The parameters Curve value specifies the type of the curve to import. + /// + /// + /// if does not contain valid values. + /// + /// + /// if references a curve that cannot be imported. + /// + /// + /// if references a curve that is not supported by this platform. + /// + public override void ImportParameters(ECParameters parameters) { - /// - /// ImportParameters will replace the existing key that ECDsaCng is working with by creating a - /// new CngKey. If the parameters contains only Q, then only a public key will be imported. - /// If the parameters also contains D, then a full key pair will be imported. - /// The parameters Curve value specifies the type of the curve to import. - /// - /// - /// if does not contain valid values. - /// - /// - /// if references a curve that cannot be imported. - /// - /// - /// if references a curve that is not supported by this platform. - /// - public override void ImportParameters(ECParameters parameters) - { - parameters.Validate(); - ThrowIfDisposed(); + parameters.Validate(); + ThrowIfDisposed(); - ECCurve curve = parameters.Curve; - bool includePrivateParameters = parameters.D != null; - bool hasPublicParameters = parameters.Q.X != null && parameters.Q.Y != null; + ECCurve curve = parameters.Curve; + bool includePrivateParameters = parameters.D != null; + bool hasPublicParameters = parameters.Q.X != null && parameters.Q.Y != null; - if (curve.IsPrime) - { - if (!hasPublicParameters && includePrivateParameters) - { - byte[] zero = new byte[parameters.D!.Length]; - ECParameters ecParamsCopy = parameters; - ecParamsCopy.Q.X = zero; - ecParamsCopy.Q.Y = zero; - byte[] ecExplicitBlob = ECCng.GetPrimeCurveBlob(ref ecParamsCopy, ecdh: false); - ImportFullKeyBlob(ecExplicitBlob, includePrivateParameters: true); - } - else - { - byte[] ecExplicitBlob = ECCng.GetPrimeCurveBlob(ref parameters, ecdh: false); - ImportFullKeyBlob(ecExplicitBlob, includePrivateParameters); - } - } - else if (curve.IsNamed) + if (curve.IsPrime) + { + if (!hasPublicParameters && includePrivateParameters) { - // FriendlyName is required; an attempt was already made to default it in ECCurve - if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) - throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value!.ToString())); - - if (!hasPublicParameters && includePrivateParameters) - { - byte[] zero = new byte[parameters.D!.Length]; - ECParameters ecParamsCopy = parameters; - ecParamsCopy.Q.X = zero; - ecParamsCopy.Q.Y = zero; - byte[] ecNamedCurveBlob = ECCng.GetNamedCurveBlob(ref ecParamsCopy, ecdh: false); - ImportKeyBlob(ecNamedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters: true); - } - else - { - byte[] ecNamedCurveBlob = ECCng.GetNamedCurveBlob(ref parameters, ecdh: false); - ImportKeyBlob(ecNamedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters); - } + byte[] zero = new byte[parameters.D!.Length]; + ECParameters ecParamsCopy = parameters; + ecParamsCopy.Q.X = zero; + ecParamsCopy.Q.Y = zero; + byte[] ecExplicitBlob = ECCng.GetPrimeCurveBlob(ref ecParamsCopy, ecdh: false); + ImportFullKeyBlob(ecExplicitBlob, includePrivateParameters: true); } else { - throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); + byte[] ecExplicitBlob = ECCng.GetPrimeCurveBlob(ref parameters, ecdh: false); + ImportFullKeyBlob(ecExplicitBlob, includePrivateParameters); } } - - /// - /// Exports the key and explicit curve parameters used by the ECC object into an object. - /// - /// - /// if there was an issue obtaining the curve values. - /// - /// - /// if explicit export is not supported by this platform. Windows 10 or higher is required. - /// - /// The key and explicit curve parameters used by the ECC object. - public override ECParameters ExportExplicitParameters(bool includePrivateParameters) + else if (curve.IsNamed) { - byte[] blob = ExportFullKeyBlob(includePrivateParameters); - ECParameters ecparams = default; - ECCng.ExportPrimeCurveParameters(ref ecparams, blob, includePrivateParameters); - return ecparams; - } - - /// - /// Exports the key used by the ECC object into an object. - /// If the curve has a name, the Curve property will contain named curve parameters otherwise it will contain explicit parameters. - /// - /// - /// if there was an issue obtaining the curve values. - /// - /// The key and named curve parameters used by the ECC object. - public override ECParameters ExportParameters(bool includePrivateParameters) - { - ECParameters ecparams = default; - - string? curveName = GetCurveName(out string? oidValue); + // FriendlyName is required; an attempt was already made to default it in ECCurve + if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value!.ToString())); - if (string.IsNullOrEmpty(curveName)) + if (!hasPublicParameters && includePrivateParameters) { - byte[] fullKeyBlob = ExportFullKeyBlob(includePrivateParameters); - ECCng.ExportPrimeCurveParameters(ref ecparams, fullKeyBlob, includePrivateParameters); + byte[] zero = new byte[parameters.D!.Length]; + ECParameters ecParamsCopy = parameters; + ecParamsCopy.Q.X = zero; + ecParamsCopy.Q.Y = zero; + byte[] ecNamedCurveBlob = ECCng.GetNamedCurveBlob(ref ecParamsCopy, ecdh: false); + ImportKeyBlob(ecNamedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters: true); } else { - byte[] keyBlob = ExportKeyBlob(includePrivateParameters); - ECCng.ExportNamedCurveParameters(ref ecparams, keyBlob, includePrivateParameters); - ecparams.Curve = ECCurve.CreateFromOid(new Oid(oidValue, curveName)); + byte[] ecNamedCurveBlob = ECCng.GetNamedCurveBlob(ref parameters, ecdh: false); + ImportKeyBlob(ecNamedCurveBlob, curve.Oid.FriendlyName, includePrivateParameters); } - - return ecparams; } - - public override void ImportPkcs8PrivateKey(ReadOnlySpan source, out int bytesRead) + else { - ThrowIfDisposed(); + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); + } + } - CngPkcs8.Pkcs8Response response = CngPkcs8.ImportPkcs8PrivateKey(source, out int localRead); + /// + /// Exports the key and explicit curve parameters used by the ECC object into an object. + /// + /// + /// if there was an issue obtaining the curve values. + /// + /// + /// if explicit export is not supported by this platform. Windows 10 or higher is required. + /// + /// The key and explicit curve parameters used by the ECC object. + public override ECParameters ExportExplicitParameters(bool includePrivateParameters) + { + byte[] blob = ExportFullKeyBlob(includePrivateParameters); + ECParameters ecparams = default; + ECCng.ExportPrimeCurveParameters(ref ecparams, blob, includePrivateParameters); + return ecparams; + } - ProcessPkcs8Response(response); - bytesRead = localRead; - } + /// + /// Exports the key used by the ECC object into an object. + /// If the curve has a name, the Curve property will contain named curve parameters otherwise it will contain explicit parameters. + /// + /// + /// if there was an issue obtaining the curve values. + /// + /// The key and named curve parameters used by the ECC object. + public override ECParameters ExportParameters(bool includePrivateParameters) + { + ECParameters ecparams = default; - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - ReadOnlySpan source, - out int bytesRead) + string? curveName = GetCurveName(out string? oidValue); + + if (string.IsNullOrEmpty(curveName)) + { + byte[] fullKeyBlob = ExportFullKeyBlob(includePrivateParameters); + ECCng.ExportPrimeCurveParameters(ref ecparams, fullKeyBlob, includePrivateParameters); + } + else { - ThrowIfDisposed(); + byte[] keyBlob = ExportKeyBlob(includePrivateParameters); + ECCng.ExportNamedCurveParameters(ref ecparams, keyBlob, includePrivateParameters); + ecparams.Curve = ECCurve.CreateFromOid(new Oid(oidValue, curveName)); + } - CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey( - passwordBytes, - source, - out int localRead); + return ecparams; + } - ProcessPkcs8Response(response); - bytesRead = localRead; - } + public override void ImportPkcs8PrivateKey(ReadOnlySpan source, out int bytesRead) + { + ThrowIfDisposed(); - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - ReadOnlySpan source, - out int bytesRead) - { - ThrowIfDisposed(); + CngPkcs8.Pkcs8Response response = CngPkcs8.ImportPkcs8PrivateKey(source, out int localRead); - CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey( - password, - source, - out int localRead); + ProcessPkcs8Response(response); + bytesRead = localRead; + } - ProcessPkcs8Response(response); - bytesRead = localRead; - } + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); - private void ProcessPkcs8Response(CngPkcs8.Pkcs8Response response) - { - // Wrong algorithm? - switch (response.GetAlgorithmGroup()) - { - // CNG ECDH and ECDSA keys can both do ECDSA. - case BCryptNative.AlgorithmName.ECDsa: - case BCryptNative.AlgorithmName.ECDH: - AcceptImport(response); - return; - } + CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey( + passwordBytes, + source, + out int localRead); - response.FreeKey(); - throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); - } + ProcessPkcs8Response(response); + bytesRead = localRead; + } - public override byte[] ExportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - PbeParameters pbeParameters) - { - if (pbeParameters == null) - throw new ArgumentNullException(nameof(pbeParameters)); + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); - return CngPkcs8.ExportEncryptedPkcs8PrivateKey( - this, - passwordBytes, - pbeParameters); - } + CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey( + password, + source, + out int localRead); + + ProcessPkcs8Response(response); + bytesRead = localRead; + } - public override byte[] ExportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - PbeParameters pbeParameters) + private void ProcessPkcs8Response(CngPkcs8.Pkcs8Response response) + { + // Wrong algorithm? + switch (response.GetAlgorithmGroup()) { - if (pbeParameters == null) - { - throw new ArgumentNullException(nameof(pbeParameters)); - } + // CNG ECDH and ECDSA keys can both do ECDSA. + case BCryptNative.AlgorithmName.ECDsa: + case BCryptNative.AlgorithmName.ECDH: + AcceptImport(response); + return; + } - PasswordBasedEncryption.ValidatePbeParameters( - pbeParameters, - password, - ReadOnlySpan.Empty); + response.FreeKey(); + throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); + } - if (CngPkcs8.IsPlatformScheme(pbeParameters)) - { - return ExportEncryptedPkcs8(password, pbeParameters.IterationCount); - } + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters) + { + if (pbeParameters == null) + throw new ArgumentNullException(nameof(pbeParameters)); - return CngPkcs8.ExportEncryptedPkcs8PrivateKey( - this, - password, - pbeParameters); - } + return CngPkcs8.ExportEncryptedPkcs8PrivateKey( + this, + passwordBytes, + pbeParameters); + } - public override bool TryExportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - PbeParameters pbeParameters, - Span destination, - out int bytesWritten) + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters) + { + if (pbeParameters == null) { - if (pbeParameters == null) - throw new ArgumentNullException(nameof(pbeParameters)); - - PasswordBasedEncryption.ValidatePbeParameters( - pbeParameters, - ReadOnlySpan.Empty, - passwordBytes); - - return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( - this, - passwordBytes, - pbeParameters, - destination, - out bytesWritten); + throw new ArgumentNullException(nameof(pbeParameters)); } - public override bool TryExportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - PbeParameters pbeParameters, - Span destination, - out int bytesWritten) + PasswordBasedEncryption.ValidatePbeParameters( + pbeParameters, + password, + ReadOnlySpan.Empty); + + if (CngPkcs8.IsPlatformScheme(pbeParameters)) { - if (pbeParameters == null) - throw new ArgumentNullException(nameof(pbeParameters)); + return ExportEncryptedPkcs8(password, pbeParameters.IterationCount); + } - PasswordBasedEncryption.ValidatePbeParameters( - pbeParameters, - password, - ReadOnlySpan.Empty); + return CngPkcs8.ExportEncryptedPkcs8PrivateKey( + this, + password, + pbeParameters); + } - if (CngPkcs8.IsPlatformScheme(pbeParameters)) - { - return TryExportEncryptedPkcs8( - password, - pbeParameters.IterationCount, - destination, - out bytesWritten); - } + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) + { + if (pbeParameters == null) + throw new ArgumentNullException(nameof(pbeParameters)); + + PasswordBasedEncryption.ValidatePbeParameters( + pbeParameters, + ReadOnlySpan.Empty, + passwordBytes); + + return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( + this, + passwordBytes, + pbeParameters, + destination, + out bytesWritten); + } + + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) + { + if (pbeParameters == null) + throw new ArgumentNullException(nameof(pbeParameters)); + + PasswordBasedEncryption.ValidatePbeParameters( + pbeParameters, + password, + ReadOnlySpan.Empty); - return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( - this, + if (CngPkcs8.IsPlatformScheme(pbeParameters)) + { + return TryExportEncryptedPkcs8( password, - pbeParameters, + pbeParameters.IterationCount, destination, out bytesWritten); } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS + + return CngPkcs8.TryExportEncryptedPkcs8PrivateKey( + this, + password, + pbeParameters, + destination, + out bytesWritten); } -#endif } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.SignVerify.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.SignVerify.cs index 0d121937d96581..8ecfd35843706a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.SignVerify.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.SignVerify.cs @@ -11,10 +11,6 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDsaImplementation - { -#endif public sealed partial class ECDsaCng : ECDsa { /// @@ -45,7 +41,6 @@ public override byte[] SignHash(byte[] hash) } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS public override bool TrySignHash(ReadOnlySpan source, Span destination, out int bytesWritten) { return TrySignHashCore( @@ -61,11 +56,6 @@ protected override unsafe bool TrySignHashCore( DSASignatureFormat signatureFormat, out int bytesWritten) { -#else - public override unsafe bool TrySignHash(ReadOnlySpan source, Span destination, out int bytesWritten) - { - ReadOnlySpan hash = source; -#endif using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) { if (!keyHandle.TrySignHash(hash, destination, AsymmetricPaddingMode.None, null, out bytesWritten)) @@ -75,7 +65,6 @@ public override unsafe bool TrySignHash(ReadOnlySpan source, Span de } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { return true; @@ -93,9 +82,6 @@ public override unsafe bool TrySignHash(ReadOnlySpan source, Span de destination.Slice(0, bytesWritten), destination, out bytesWritten); -#else - return true; -#endif } /// @@ -108,14 +94,9 @@ public override bool VerifyHash(byte[] hash, byte[] signature) if (signature == null) throw new ArgumentNullException(nameof(signature)); -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS return VerifyHashCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation); -#else - return VerifyHash((ReadOnlySpan)hash, (ReadOnlySpan)signature); -#endif } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan signature) => VerifyHashCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation); @@ -123,16 +104,12 @@ protected override bool VerifyHashCore( ReadOnlySpan hash, ReadOnlySpan signature, DSASignatureFormat signatureFormat) -#else - public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan signature) -#endif { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS if (signatureFormat != DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { signature = this.ConvertSignatureToIeeeP1363(signatureFormat, signature); } -#endif + using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) { unsafe @@ -142,7 +119,4 @@ public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan sign } } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.cs index 4a6c655fb82e7c..082608c735dc34 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.cs @@ -1,95 +1,90 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using static Internal.NativeCrypto.BCryptNative; +using System.Runtime.Versioning; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDsaImplementation + public sealed partial class ECDsaCng : ECDsa { -#endif - public sealed partial class ECDsaCng : ECDsa + /// + /// Create an ECDsaCng algorithm with a named curve. + /// + /// The representing the curve. + /// if is null. + /// if does not contain an Oid with a FriendlyName. + [SupportedOSPlatform("windows")] + public ECDsaCng(ECCurve curve) { - /// - /// Create an ECDsaCng algorithm with a named curve. - /// - /// The representing the curve. - /// if is null. - /// if does not contain an Oid with a FriendlyName. - public ECDsaCng(ECCurve curve) - { - // Specified curves generate the key immediately - GenerateKey(curve); - } + // Specified curves generate the key immediately + GenerateKey(curve); + } - /// - /// Create an ECDsaCng algorithm with a random 521 bit key pair. - /// - public ECDsaCng() - : this(521) - { - } + /// + /// Create an ECDsaCng algorithm with a random 521 bit key pair. + /// + [SupportedOSPlatform("windows")] + public ECDsaCng() + : this(521) + { + } - /// - /// Creates a new ECDsaCng object that will use a randomly generated key of the specified size. - /// - /// Size of the key to generate, in bits. - /// if is not valid - public ECDsaCng(int keySize) + /// + /// Creates a new ECDsaCng object that will use a randomly generated key of the specified size. + /// + /// Size of the key to generate, in bits. + /// if is not valid + [SupportedOSPlatform("windows")] + public ECDsaCng(int keySize) + { + KeySize = keySize; + } + + public override int KeySize + { + get { - KeySize = keySize; + return base.KeySize; } - - public override int KeySize + set { - get + if (KeySize == value) { - return base.KeySize; + return; } - set - { - if (KeySize == value) - { - return; - } - // Set the KeySize before DisposeKey so that an invalid value doesn't throw away the key - base.KeySize = value; + // Set the KeySize before DisposeKey so that an invalid value doesn't throw away the key + base.KeySize = value; - DisposeKey(); + DisposeKey(); - // Key will be lazily re-created - } + // Key will be lazily re-created } + } - /// - /// Set the KeySize without validating against LegalKeySizes. - /// - /// The value to set the KeySize to. - private void ForceSetKeySize(int newKeySize) - { - // In the event that a key was loaded via ImportParameters, curve name, or an IntPtr/SafeHandle - // it could be outside of the bounds that we currently represent as "legal key sizes". - // Since that is our view into the underlying component it can be detached from the - // component's understanding. If it said it has opened a key, and this is the size, trust it. - KeySizeValue = newKeySize; - } + /// + /// Set the KeySize without validating against LegalKeySizes. + /// + /// The value to set the KeySize to. + private void ForceSetKeySize(int newKeySize) + { + // In the event that a key was loaded via ImportParameters, curve name, or an IntPtr/SafeHandle + // it could be outside of the bounds that we currently represent as "legal key sizes". + // Since that is our view into the underlying component it can be detached from the + // component's understanding. If it said it has opened a key, and this is the size, trust it. + KeySizeValue = newKeySize; + } - public override KeySizes[] LegalKeySizes + public override KeySizes[] LegalKeySizes + { + get { - get - { - // Return the three sizes that can be explicitly set (for backwards compatibility) - return new[] { - new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), - new KeySizes(minSize: 521, maxSize: 521, skipSize: 0), - }; - } + // Return the three sizes that can be explicitly set (for backwards compatibility) + return new[] { + new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), + new KeySizes(minSize: 521, maxSize: 521, skipSize: 0), + }; } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDsaOpenSsl.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDsaOpenSsl.cs index c56d3f4affa78c..898fe32d37dc5d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDsaOpenSsl.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDsaOpenSsl.cs @@ -3,369 +3,356 @@ using System.Diagnostics; using System.IO; +using System.Runtime.Versioning; using Internal.Cryptography; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class ECDsaImplementation + public sealed partial class ECDsaOpenSsl : ECDsa { -#endif - public sealed partial class ECDsaOpenSsl : ECDsa + // secp521r1 maxes out at 139 bytes, so 256 should always be enough + private const int SignatureStackBufSize = 256; + + private ECOpenSsl _key; + + /// + /// Create an ECDsaOpenSsl algorithm with a named curve. + /// + /// The representing the curve. + /// if is null. + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDsaOpenSsl(ECCurve curve) { - // secp521r1 maxes out at 139 bytes, so 256 should always be enough - private const int SignatureStackBufSize = 256; + ThrowIfNotSupported(); + _key = new ECOpenSsl(curve); + ForceSetKeySize(_key.KeySize); + } - private ECOpenSsl _key; + /// + /// Create an ECDsaOpenSsl algorithm with a random 521 bit key pair. + /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDsaOpenSsl() + : this(521) + { + } - /// - /// Create an ECDsaOpenSsl algorithm with a named curve. - /// - /// The representing the curve. - /// if is null. - public ECDsaOpenSsl(ECCurve curve) - { - ThrowIfNotSupported(); - _key = new ECOpenSsl(curve); - ForceSetKeySize(_key.KeySize); - } + /// + /// Creates a new ECDsaOpenSsl object that will use a randomly generated key of the specified size. + /// + /// Size of the key to generate, in bits. + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDsaOpenSsl(int keySize) + { + ThrowIfNotSupported(); + // Use the base setter to get the validation and field assignment without the + // side effect of dereferencing _key. + base.KeySize = keySize; + _key = new ECOpenSsl(this); + } - /// - /// Create an ECDsaOpenSsl algorithm with a random 521 bit key pair. - /// - public ECDsaOpenSsl() - : this(521) - { - } + /// + /// Set the KeySize without validating against LegalKeySizes. + /// + /// The value to set the KeySize to. + private void ForceSetKeySize(int newKeySize) + { + // In the event that a key was loaded via ImportParameters, curve name, or an IntPtr/SafeHandle + // it could be outside of the bounds that we currently represent as "legal key sizes". + // Since that is our view into the underlying component it can be detached from the + // component's understanding. If it said it has opened a key, and this is the size, trust it. + KeySizeValue = newKeySize; + } - /// - /// Creates a new ECDsaOpenSsl object that will use a randomly generated key of the specified size. - /// - /// Size of the key to generate, in bits. - public ECDsaOpenSsl(int keySize) + public override KeySizes[] LegalKeySizes + { + get { - ThrowIfNotSupported(); - // Use the base setter to get the validation and field assignment without the - // side effect of dereferencing _key. - base.KeySize = keySize; - _key = new ECOpenSsl(this); + // Return the three sizes that can be explicitly set (for backwards compatibility) + return new[] { + new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), + new KeySizes(minSize: 521, maxSize: 521, skipSize: 0), + }; } + } - /// - /// Set the KeySize without validating against LegalKeySizes. - /// - /// The value to set the KeySize to. - private void ForceSetKeySize(int newKeySize) - { - // In the event that a key was loaded via ImportParameters, curve name, or an IntPtr/SafeHandle - // it could be outside of the bounds that we currently represent as "legal key sizes". - // Since that is our view into the underlying component it can be detached from the - // component's understanding. If it said it has opened a key, and this is the size, trust it. - KeySizeValue = newKeySize; - } + public override byte[] SignHash(byte[] hash) + { + if (hash == null) + throw new ArgumentNullException(nameof(hash)); - public override KeySizes[] LegalKeySizes - { - get - { - // Return the three sizes that can be explicitly set (for backwards compatibility) - return new[] { - new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), - new KeySizes(minSize: 521, maxSize: 521, skipSize: 0), - }; - } - } + ThrowIfDisposed(); + SafeEcKeyHandle key = _key.Value; + int signatureLength = Interop.Crypto.EcDsaSize(key); - public override byte[] SignHash(byte[] hash) - { - if (hash == null) - throw new ArgumentNullException(nameof(hash)); + Span signDestination = stackalloc byte[SignatureStackBufSize]; + ReadOnlySpan derSignature = SignHash(hash, signDestination, signatureLength, key); - ThrowIfDisposed(); - SafeEcKeyHandle key = _key.Value; - int signatureLength = Interop.Crypto.EcDsaSize(key); + byte[] converted = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, KeySize); + return converted; + } - Span signDestination = stackalloc byte[SignatureStackBufSize]; - ReadOnlySpan derSignature = SignHash(hash, signDestination, signatureLength, key); + public override bool TrySignHash(ReadOnlySpan hash, Span destination, out int bytesWritten) + { + return TrySignHashCore( + hash, + destination, + DSASignatureFormat.IeeeP1363FixedFieldConcatenation, + out bytesWritten); + } - byte[] converted = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, KeySize); - return converted; - } + protected override bool TrySignHashCore( + ReadOnlySpan hash, + Span destination, + DSASignatureFormat signatureFormat, + out int bytesWritten) + { + ThrowIfDisposed(); + SafeEcKeyHandle key = _key.Value; -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - public override bool TrySignHash(ReadOnlySpan hash, Span destination, out int bytesWritten) - { - return TrySignHashCore( - hash, - destination, - DSASignatureFormat.IeeeP1363FixedFieldConcatenation, - out bytesWritten); - } + int signatureLength = Interop.Crypto.EcDsaSize(key); + Span signDestination = stackalloc byte[SignatureStackBufSize]; - protected override bool TrySignHashCore( - ReadOnlySpan hash, - Span destination, - DSASignatureFormat signatureFormat, - out int bytesWritten) -#else - public override bool TrySignHash(ReadOnlySpan hash, Span destination, out int bytesWritten) -#endif + if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { - ThrowIfDisposed(); - SafeEcKeyHandle key = _key.Value; - - int signatureLength = Interop.Crypto.EcDsaSize(key); - Span signDestination = stackalloc byte[SignatureStackBufSize]; + int encodedSize = 2 * AsymmetricAlgorithmHelpers.BitsToBytes(KeySize); -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) - { -#endif - int encodedSize = 2 * AsymmetricAlgorithmHelpers.BitsToBytes(KeySize); - - if (destination.Length < encodedSize) - { - bytesWritten = 0; - return false; - } - - ReadOnlySpan derSignature = SignHash(hash, signDestination, signatureLength, key); - bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, KeySize, destination); - Debug.Assert(bytesWritten == encodedSize); - return true; -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - } - else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) - { - if (destination.Length >= signatureLength) - { - signDestination = destination; - } - else if (signatureLength > signDestination.Length) - { - Debug.Fail($"Stack-based signDestination is insufficient ({signatureLength} needed)"); - bytesWritten = 0; - return false; - } - - ReadOnlySpan derSignature = SignHash(hash, signDestination, signatureLength, key); - - if (destination == signDestination) - { - bytesWritten = derSignature.Length; - return true; - } - - return Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten); - } - else + if (destination.Length < encodedSize) { - throw new ArgumentOutOfRangeException(nameof(signatureFormat)); + bytesWritten = 0; + return false; } -#endif - } - private static ReadOnlySpan SignHash( - ReadOnlySpan hash, - Span destination, - int signatureLength, - SafeEcKeyHandle key) + ReadOnlySpan derSignature = SignHash(hash, signDestination, signatureLength, key); + bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, KeySize, destination); + Debug.Assert(bytesWritten == encodedSize); + return true; + } + else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) { - if (signatureLength > destination.Length) + if (destination.Length >= signatureLength) + { + signDestination = destination; + } + else if (signatureLength > signDestination.Length) { Debug.Fail($"Stack-based signDestination is insufficient ({signatureLength} needed)"); - destination = new byte[signatureLength]; + bytesWritten = 0; + return false; } - if (!Interop.Crypto.EcDsaSign(hash, destination, out int actualLength, key)) + ReadOnlySpan derSignature = SignHash(hash, signDestination, signatureLength, key); + + if (destination == signDestination) { - throw Interop.Crypto.CreateOpenSslCryptographicException(); + bytesWritten = derSignature.Length; + return true; } - Debug.Assert( - actualLength <= signatureLength, - "ECDSA_sign reported an unexpected signature size", - "ECDSA_sign reported signatureSize was {0}, when <= {1} was expected", - actualLength, - signatureLength); - - return destination.Slice(0, actualLength); + return Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten); } - - public override bool VerifyHash(byte[] hash, byte[] signature) + else { - if (hash == null) - throw new ArgumentNullException(nameof(hash)); - if (signature == null) - throw new ArgumentNullException(nameof(signature)); + throw new ArgumentOutOfRangeException(nameof(signatureFormat)); + } + } - return VerifyHash((ReadOnlySpan)hash, (ReadOnlySpan)signature); + private static ReadOnlySpan SignHash( + ReadOnlySpan hash, + Span destination, + int signatureLength, + SafeEcKeyHandle key) + { + if (signatureLength > destination.Length) + { + Debug.Fail($"Stack-based signDestination is insufficient ({signatureLength} needed)"); + destination = new byte[signatureLength]; } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan signature) => - VerifyHashCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation); - - protected override bool VerifyHashCore( - ReadOnlySpan hash, - ReadOnlySpan signature, - DSASignatureFormat signatureFormat) -#else - public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan signature) -#endif + if (!Interop.Crypto.EcDsaSign(hash, destination, out int actualLength, key)) { - ThrowIfDisposed(); + throw Interop.Crypto.CreateOpenSslCryptographicException(); + } - Span derSignature = stackalloc byte[SignatureStackBufSize]; - ReadOnlySpan toVerify = derSignature; + Debug.Assert( + actualLength <= signatureLength, + "ECDSA_sign reported an unexpected signature size", + "ECDSA_sign reported signatureSize was {0}, when <= {1} was expected", + actualLength, + signatureLength); -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) - { -#endif - // The signature format for .NET is r.Concat(s). Each of r and s are of length BitsToBytes(KeySize), even - // when they would have leading zeroes. If it's the correct size, then we need to encode it from - // r.Concat(s) to SEQUENCE(INTEGER(r), INTEGER(s)), because that's the format that OpenSSL expects. - int expectedBytes = 2 * AsymmetricAlgorithmHelpers.BitsToBytes(KeySize); - if (signature.Length != expectedBytes) - { - // The input isn't of the right length, so we can't sensibly re-encode it. - return false; - } - - if (AsymmetricAlgorithmHelpers.TryConvertIeee1363ToDer(signature, derSignature, out int derSize)) - { - toVerify = derSignature.Slice(0, derSize); - } - else - { - toVerify = AsymmetricAlgorithmHelpers.ConvertIeee1363ToDer(signature); - } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - } - else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) - { - toVerify = signature; - } - else - { - Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); - throw new CryptographicException( - SR.Cryptography_UnknownSignatureFormat, - signatureFormat.ToString()); - } -#endif + return destination.Slice(0, actualLength); + } - SafeEcKeyHandle key = _key.Value; - int verifyResult = Interop.Crypto.EcDsaVerify(hash, toVerify, key); - return verifyResult == 1; - } + public override bool VerifyHash(byte[] hash, byte[] signature) + { + if (hash == null) + throw new ArgumentNullException(nameof(hash)); + if (signature == null) + throw new ArgumentNullException(nameof(signature)); - protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => - AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm); + return VerifyHash((ReadOnlySpan)hash, (ReadOnlySpan)signature); + } + + public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan signature) => + VerifyHashCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation); - protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => - AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm); + protected override bool VerifyHashCore( + ReadOnlySpan hash, + ReadOnlySpan signature, + DSASignatureFormat signatureFormat) + { + ThrowIfDisposed(); - protected override bool TryHashData(ReadOnlySpan data, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) => - AsymmetricAlgorithmHelpers.TryHashData(data, destination, hashAlgorithm, out bytesWritten); + Span derSignature = stackalloc byte[SignatureStackBufSize]; + ReadOnlySpan toVerify = derSignature; - protected override void Dispose(bool disposing) + if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { - if (disposing) + // The signature format for .NET is r.Concat(s). Each of r and s are of length BitsToBytes(KeySize), even + // when they would have leading zeroes. If it's the correct size, then we need to encode it from + // r.Concat(s) to SEQUENCE(INTEGER(r), INTEGER(s)), because that's the format that OpenSSL expects. + int expectedBytes = 2 * AsymmetricAlgorithmHelpers.BitsToBytes(KeySize); + if (signature.Length != expectedBytes) { - _key?.Dispose(); - _key = null!; + // The input isn't of the right length, so we can't sensibly re-encode it. + return false; } - base.Dispose(disposing); - } - - public override int KeySize - { - get + if (AsymmetricAlgorithmHelpers.TryConvertIeee1363ToDer(signature, derSignature, out int derSize)) { - return base.KeySize; + toVerify = derSignature.Slice(0, derSize); } - set + else { - if (KeySize == value) - return; - - // Set the KeySize before FreeKey so that an invalid value doesn't throw away the key - base.KeySize = value; - - ThrowIfDisposed(); - _key.Dispose(); - _key = new ECOpenSsl(this); + toVerify = AsymmetricAlgorithmHelpers.ConvertIeee1363ToDer(signature); } } - - public override void GenerateKey(ECCurve curve) + else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) { - ThrowIfDisposed(); - _key.GenerateKey(curve); - - // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere - // with the already loaded key. - ForceSetKeySize(_key.KeySize); + toVerify = signature; } - - public override void ImportParameters(ECParameters parameters) + else { - ThrowIfDisposed(); - _key.ImportParameters(parameters); - ForceSetKeySize(_key.KeySize); + Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); + throw new CryptographicException( + SR.Cryptography_UnknownSignatureFormat, + signatureFormat.ToString()); } - public override ECParameters ExportExplicitParameters(bool includePrivateParameters) - { - ThrowIfDisposed(); - return ECOpenSsl.ExportExplicitParameters(_key.Value, includePrivateParameters); - } + SafeEcKeyHandle key = _key.Value; + int verifyResult = Interop.Crypto.EcDsaVerify(hash, toVerify, key); + return verifyResult == 1; + } + + protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => + AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm); - public override ECParameters ExportParameters(bool includePrivateParameters) + protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => + AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm); + + protected override bool TryHashData(ReadOnlySpan data, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) => + AsymmetricAlgorithmHelpers.TryHashData(data, destination, hashAlgorithm, out bytesWritten); + + protected override void Dispose(bool disposing) + { + if (disposing) { - ThrowIfDisposed(); - return ECOpenSsl.ExportParameters(_key.Value, includePrivateParameters); + _key?.Dispose(); + _key = null!; } - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - ReadOnlySpan source, - out int bytesRead) + base.Dispose(disposing); + } + + public override int KeySize + { + get { - ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + return base.KeySize; } - - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - ReadOnlySpan source, - out int bytesRead) + set { + if (KeySize == value) + return; + + // Set the KeySize before FreeKey so that an invalid value doesn't throw away the key + base.KeySize = value; + ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + _key.Dispose(); + _key = new ECOpenSsl(this); } + } + + public override void GenerateKey(ECCurve curve) + { + ThrowIfDisposed(); + _key.GenerateKey(curve); + + // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere + // with the already loaded key. + ForceSetKeySize(_key.KeySize); + } + + public override void ImportParameters(ECParameters parameters) + { + ThrowIfDisposed(); + _key.ImportParameters(parameters); + ForceSetKeySize(_key.KeySize); + } + + public override ECParameters ExportExplicitParameters(bool includePrivateParameters) + { + ThrowIfDisposed(); + return ECOpenSsl.ExportExplicitParameters(_key.Value, includePrivateParameters); + } + + public override ECParameters ExportParameters(bool includePrivateParameters) + { + ThrowIfDisposed(); + return ECOpenSsl.ExportParameters(_key.Value, includePrivateParameters); + } - private void ThrowIfDisposed() + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + } + + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + } + + private void ThrowIfDisposed() + { + if (_key == null) { - if (_key == null) - { - throw new ObjectDisposedException( -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - nameof(ECDsa) -#else - nameof(ECDsaOpenSsl) -#endif - ); - } + throw new ObjectDisposedException(nameof(ECDsaOpenSsl)); } - - static partial void ThrowIfNotSupported(); } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS + + static partial void ThrowIfNotSupported(); } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/ECDsaSecurityTransforms.cs b/src/libraries/Common/src/System/Security/Cryptography/ECDsaSecurityTransforms.cs index c1f9852191a4b0..0f4bcb418c89b2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/ECDsaSecurityTransforms.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/ECDsaSecurityTransforms.cs @@ -7,248 +7,213 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - public partial class ECDsa : ECAlgorithm + internal static partial class ECDsaImplementation { - /// - /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. - /// - public static new partial ECDsa Create() + public sealed partial class ECDsaSecurityTransforms : ECDsa { - return new ECDsaImplementation.ECDsaSecurityTransforms(); - } + private readonly EccSecurityTransforms _ecc = new EccSecurityTransforms(nameof(ECDsa)); - /// - /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. - /// - /// - /// The representing the elliptic curve. - /// - public static partial ECDsa Create(ECCurve curve) - { - ECDsa ecdsa = Create(); - ecdsa.GenerateKey(curve); - return ecdsa; - } + public ECDsaSecurityTransforms() + { + base.KeySize = 521; + } - /// - /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. - /// - /// - /// The representing the elliptic curve parameters. - /// - public static partial ECDsa Create(ECParameters parameters) - { - ECDsa ecdsa = Create(); - ecdsa.ImportParameters(parameters); - return ecdsa; - } -#endif - internal static partial class ECDsaImplementation - { - public sealed partial class ECDsaSecurityTransforms : ECDsa + internal ECDsaSecurityTransforms(SafeSecKeyRefHandle publicKey) + { + KeySizeValue = _ecc.SetKeyAndGetSize(SecKeyPair.PublicOnly(publicKey)); + } + + internal ECDsaSecurityTransforms(SafeSecKeyRefHandle publicKey, SafeSecKeyRefHandle privateKey) { - private readonly EccSecurityTransforms _ecc = new EccSecurityTransforms(nameof(ECDsa)); + KeySizeValue = _ecc.SetKeyAndGetSize(SecKeyPair.PublicPrivatePair(publicKey, privateKey)); + } - public ECDsaSecurityTransforms() + public override KeySizes[] LegalKeySizes + { + get { - base.KeySize = 521; + // Return the three sizes that can be explicitly set (for backwards compatibility) + return new[] { + new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), + new KeySizes(minSize: 521, maxSize: 521, skipSize: 0), + }; } + } - internal ECDsaSecurityTransforms(SafeSecKeyRefHandle publicKey) + public override int KeySize + { + get { - KeySizeValue = _ecc.SetKeyAndGetSize(SecKeyPair.PublicOnly(publicKey)); + return base.KeySize; } - - internal ECDsaSecurityTransforms(SafeSecKeyRefHandle publicKey, SafeSecKeyRefHandle privateKey) + set { - KeySizeValue = _ecc.SetKeyAndGetSize(SecKeyPair.PublicPrivatePair(publicKey, privateKey)); + if (KeySize == value) + return; + + // Set the KeySize before freeing the key so that an invalid value doesn't throw away the key + base.KeySize = value; + _ecc.DisposeKey(); } + } - public override KeySizes[] LegalKeySizes + public override byte[] SignHash(byte[] hash) + { + if (hash == null) + throw new ArgumentNullException(nameof(hash)); + + SecKeyPair keys = GetKeys(); + + if (keys.PrivateKey == null) { - get - { - // Return the three sizes that can be explicitly set (for backwards compatibility) - return new[] { - new KeySizes(minSize: 256, maxSize: 384, skipSize: 128), - new KeySizes(minSize: 521, maxSize: 521, skipSize: 0), - }; - } + throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); } - public override int KeySize + byte[] derFormatSignature = Interop.AppleCrypto.CreateSignature( + keys.PrivateKey, + hash, + Interop.AppleCrypto.PAL_HashAlgorithm.Unknown, + Interop.AppleCrypto.PAL_SignatureAlgorithm.EC); + byte[] ieeeFormatSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363( + derFormatSignature.AsSpan(0, derFormatSignature.Length), + KeySize); + + return ieeeFormatSignature; + } + + public override bool TrySignHash(ReadOnlySpan source, Span destination, out int bytesWritten) + { + SecKeyPair keys = GetKeys(); + if (keys.PrivateKey == null) { - get - { - return base.KeySize; - } - set - { - if (KeySize == value) - return; - - // Set the KeySize before freeing the key so that an invalid value doesn't throw away the key - base.KeySize = value; - _ecc.DisposeKey(); - } + throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); } - public override byte[] SignHash(byte[] hash) + byte[] derFormatSignature = Interop.AppleCrypto.CreateSignature( + keys.PrivateKey, + source, + Interop.AppleCrypto.PAL_HashAlgorithm.Unknown, + Interop.AppleCrypto.PAL_SignatureAlgorithm.EC); + byte[] ieeeFormatSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363( + derFormatSignature.AsSpan(0, derFormatSignature.Length), + KeySize); + + if (ieeeFormatSignature.Length <= destination.Length) { - if (hash == null) - throw new ArgumentNullException(nameof(hash)); - - SecKeyPair keys = GetKeys(); - - if (keys.PrivateKey == null) - { - throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); - } - - byte[] derFormatSignature = Interop.AppleCrypto.CreateSignature( - keys.PrivateKey, - hash, - Interop.AppleCrypto.PAL_HashAlgorithm.Unknown, - Interop.AppleCrypto.PAL_SignatureAlgorithm.EC); - byte[] ieeeFormatSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363( - derFormatSignature.AsSpan(0, derFormatSignature.Length), - KeySize); - - return ieeeFormatSignature; + new ReadOnlySpan(ieeeFormatSignature).CopyTo(destination); + bytesWritten = ieeeFormatSignature.Length; + return true; } - - public override bool TrySignHash(ReadOnlySpan source, Span destination, out int bytesWritten) + else { - SecKeyPair keys = GetKeys(); - if (keys.PrivateKey == null) - { - throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); - } - - byte[] derFormatSignature = Interop.AppleCrypto.CreateSignature( - keys.PrivateKey, - source, - Interop.AppleCrypto.PAL_HashAlgorithm.Unknown, - Interop.AppleCrypto.PAL_SignatureAlgorithm.EC); - byte[] ieeeFormatSignature = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363( - derFormatSignature.AsSpan(0, derFormatSignature.Length), - KeySize); - - if (ieeeFormatSignature.Length <= destination.Length) - { - new ReadOnlySpan(ieeeFormatSignature).CopyTo(destination); - bytesWritten = ieeeFormatSignature.Length; - return true; - } - else - { - bytesWritten = 0; - return false; - } + bytesWritten = 0; + return false; } + } - public override bool VerifyHash(byte[] hash, byte[] signature) - { - if (hash == null) - throw new ArgumentNullException(nameof(hash)); - if (signature == null) - throw new ArgumentNullException(nameof(signature)); + public override bool VerifyHash(byte[] hash, byte[] signature) + { + if (hash == null) + throw new ArgumentNullException(nameof(hash)); + if (signature == null) + throw new ArgumentNullException(nameof(signature)); - return VerifyHash((ReadOnlySpan)hash, (ReadOnlySpan)signature); - } + return VerifyHash((ReadOnlySpan)hash, (ReadOnlySpan)signature); + } - public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan signature) + public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan signature) + { + ThrowIfDisposed(); + + // The signature format for .NET is r.Concat(s). Each of r and s are of length BitsToBytes(KeySize), even + // when they would have leading zeroes. If it's the correct size, then we need to encode it from + // r.Concat(s) to SEQUENCE(INTEGER(r), INTEGER(s)), because that's the format that OpenSSL expects. + int expectedBytes = 2 * AsymmetricAlgorithmHelpers.BitsToBytes(KeySize); + if (signature.Length != expectedBytes) { - ThrowIfDisposed(); - - // The signature format for .NET is r.Concat(s). Each of r and s are of length BitsToBytes(KeySize), even - // when they would have leading zeroes. If it's the correct size, then we need to encode it from - // r.Concat(s) to SEQUENCE(INTEGER(r), INTEGER(s)), because that's the format that OpenSSL expects. - int expectedBytes = 2 * AsymmetricAlgorithmHelpers.BitsToBytes(KeySize); - if (signature.Length != expectedBytes) - { - // The input isn't of the right length, so we can't sensibly re-encode it. - return false; - } - - return Interop.AppleCrypto.VerifySignature( - GetKeys().PublicKey, - hash, - AsymmetricAlgorithmHelpers.ConvertIeee1363ToDer(signature), - Interop.AppleCrypto.PAL_HashAlgorithm.Unknown, - Interop.AppleCrypto.PAL_SignatureAlgorithm.EC); + // The input isn't of the right length, so we can't sensibly re-encode it. + return false; } - protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => - AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm); + return Interop.AppleCrypto.VerifySignature( + GetKeys().PublicKey, + hash, + AsymmetricAlgorithmHelpers.ConvertIeee1363ToDer(signature), + Interop.AppleCrypto.PAL_HashAlgorithm.Unknown, + Interop.AppleCrypto.PAL_SignatureAlgorithm.EC); + } + + protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => + AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm); - protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => - AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm); + protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => + AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm); - protected override bool TryHashData(ReadOnlySpan source, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) => - AsymmetricAlgorithmHelpers.TryHashData(source, destination, hashAlgorithm, out bytesWritten); + protected override bool TryHashData(ReadOnlySpan source, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) => + AsymmetricAlgorithmHelpers.TryHashData(source, destination, hashAlgorithm, out bytesWritten); - private void ThrowIfDisposed() + private void ThrowIfDisposed() + { + _ecc.ThrowIfDisposed(); + } + + protected override void Dispose(bool disposing) + { + if (disposing) { - _ecc.ThrowIfDisposed(); + _ecc.Dispose(); } - protected override void Dispose(bool disposing) - { - if (disposing) - { - _ecc.Dispose(); - } + base.Dispose(disposing); + } - base.Dispose(disposing); - } + public override ECParameters ExportExplicitParameters(bool includePrivateParameters) + { + throw new PlatformNotSupportedException(SR.Cryptography_ECC_NamedCurvesOnly); + } - public override ECParameters ExportExplicitParameters(bool includePrivateParameters) - { - throw new PlatformNotSupportedException(SR.Cryptography_ECC_NamedCurvesOnly); - } + public override ECParameters ExportParameters(bool includePrivateParameters) + { + return _ecc.ExportParameters(includePrivateParameters, KeySize); + } - public override ECParameters ExportParameters(bool includePrivateParameters) - { - return _ecc.ExportParameters(includePrivateParameters, KeySize); - } + internal bool TryExportDataKeyParameters(bool includePrivateParameters, ref ECParameters ecParameters) + { + return _ecc.TryExportDataKeyParameters(includePrivateParameters, KeySize, ref ecParameters); + } - public override void ImportParameters(ECParameters parameters) - { - KeySizeValue = _ecc.ImportParameters(parameters); - } + public override void ImportParameters(ECParameters parameters) + { + KeySizeValue = _ecc.ImportParameters(parameters); + } - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan passwordBytes, - ReadOnlySpan source, - out int bytesRead) - { - ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); - } + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + } - public override void ImportEncryptedPkcs8PrivateKey( - ReadOnlySpan password, - ReadOnlySpan source, - out int bytesRead) - { - ThrowIfDisposed(); - base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); - } + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) + { + ThrowIfDisposed(); + base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + } - public override void GenerateKey(ECCurve curve) - { - KeySizeValue = _ecc.GenerateKey(curve); - } + public override void GenerateKey(ECCurve curve) + { + KeySizeValue = _ecc.GenerateKey(curve); + } - internal SecKeyPair GetKeys() - { - return _ecc.GetOrGenerateKeys(KeySize); - } + internal SecKeyPair GetKeys() + { + return _ecc.GetOrGenerateKeys(KeySize); } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/EccSecurityTransforms.cs b/src/libraries/Common/src/System/Security/Cryptography/EccSecurityTransforms.cs index 6d16c38f68baa2..9c73fca281ca7f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/EccSecurityTransforms.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/EccSecurityTransforms.cs @@ -119,7 +119,32 @@ private void SetKey(SecKeyPair keyPair) internal ECParameters ExportParameters(bool includePrivateParameters, int keySizeInBits) { SecKeyPair keys = GetOrGenerateKeys(keySizeInBits); + ECParameters key = default; + if (!TryExportDataKeyParameters(keys, includePrivateParameters, ref key)) + { + return ExportParametersFromLegacyKey(keys, includePrivateParameters); + } + + return key; + } + + internal bool TryExportDataKeyParameters( + bool includePrivateParameters, + int keySizeInBits, + ref ECParameters ecParameters) + { + return TryExportDataKeyParameters( + GetOrGenerateKeys(keySizeInBits), + includePrivateParameters, + ref ecParameters); + } + + private static bool TryExportDataKeyParameters( + SecKeyPair keys, + bool includePrivateParameters, + ref ECParameters ecParameters) + { if (includePrivateParameters && keys.PrivateKey == null) { throw new CryptographicException(SR.Cryptography_OpenInvalidHandle); @@ -131,7 +156,7 @@ internal ECParameters ExportParameters(bool includePrivateParameters, int keySiz if (!gotKeyBlob) { - return ExportParametersFromLegacyKey(keys, includePrivateParameters); + return false; } try @@ -139,19 +164,19 @@ internal ECParameters ExportParameters(bool includePrivateParameters, int keySiz AsymmetricAlgorithmHelpers.DecodeFromUncompressedAnsiX963Key( keyBlob, includePrivateParameters, - out ECParameters key); + out ecParameters); switch (GetKeySize(keys)) { - case 256: key.Curve = ECCurve.NamedCurves.nistP256; break; - case 384: key.Curve = ECCurve.NamedCurves.nistP384; break; - case 521: key.Curve = ECCurve.NamedCurves.nistP521; break; + case 256: ecParameters.Curve = ECCurve.NamedCurves.nistP256; break; + case 384: ecParameters.Curve = ECCurve.NamedCurves.nistP384; break; + case 521: ecParameters.Curve = ECCurve.NamedCurves.nistP521; break; default: Debug.Fail("Unsupported curve"); throw new CryptographicException(); } - return key; + return true; } finally { diff --git a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs index 22fff97677f615..e1f5045cf3d1bb 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/HashOneShotHelpers.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography; +using System.IO; namespace System.Security.Cryptography { @@ -9,7 +10,59 @@ namespace System.Security.Cryptography [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "Weak algorithms are used as instructed by the caller")] internal static class HashOneShotHelpers { - public static int MacData( + internal static byte[] HashData(HashAlgorithmName hashAlgorithm, ReadOnlySpan source) + { + if (hashAlgorithm == HashAlgorithmName.SHA256) + { + return SHA256.HashData(source); + } + else if (hashAlgorithm == HashAlgorithmName.SHA1) + { + return SHA1.HashData(source); + } + else if (hashAlgorithm == HashAlgorithmName.SHA512) + { + return SHA512.HashData(source); + } + else if (hashAlgorithm == HashAlgorithmName.SHA384) + { + return SHA384.HashData(source); + } + else if (Helpers.HasMD5 && hashAlgorithm == HashAlgorithmName.MD5) + { + return MD5.HashData(source); + } + + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)); + } + + internal static byte[] HashData(HashAlgorithmName hashAlgorithm, Stream source) + { + if (hashAlgorithm == HashAlgorithmName.SHA256) + { + return SHA256.HashData(source); + } + else if (hashAlgorithm == HashAlgorithmName.SHA1) + { + return SHA1.HashData(source); + } + else if (hashAlgorithm == HashAlgorithmName.SHA512) + { + return SHA512.HashData(source); + } + else if (hashAlgorithm == HashAlgorithmName.SHA384) + { + return SHA384.HashData(source); + } + else if (Helpers.HasMD5 && hashAlgorithm == HashAlgorithmName.MD5) + { + return MD5.HashData(source); + } + + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)); + } + + internal static int MacData( HashAlgorithmName hashAlgorithm, ReadOnlySpan key, ReadOnlySpan source, diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs b/src/libraries/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs index ace52b302c5520..856cf4b6f2aa21 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSACng.EncryptDecrypt.cs @@ -11,10 +11,6 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class RSAImplementation - { -#endif public sealed partial class RSACng : RSA { private const int Pkcs1PaddingOverhead = 11; @@ -319,7 +315,4 @@ private static unsafe ErrorCode EncryptOrDecrypt( return errorCode; } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSACng.ImportExport.cs b/src/libraries/Common/src/System/Security/Cryptography/RSACng.ImportExport.cs index 67328cb35e8a78..66206156ece89e 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSACng.ImportExport.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSACng.ImportExport.cs @@ -11,10 +11,6 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class RSAImplementation - { -#endif public sealed partial class RSACng : RSA { /// @@ -372,7 +368,4 @@ private static void CheckMagicValueOfKey(KeyBlobMagicNumber magic, bool includeP } } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSACng.SignVerify.cs b/src/libraries/Common/src/System/Security/Cryptography/RSACng.SignVerify.cs index 27fc35493783f6..947a73416d7d37 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSACng.SignVerify.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSACng.SignVerify.cs @@ -13,10 +13,6 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal static partial class RSAImplementation - { -#endif public sealed partial class RSACng : RSA { private static readonly ConcurrentDictionary s_hashSizes = @@ -182,7 +178,4 @@ public override unsafe bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan /// Create an RSACng algorithm with a random 2048 bit key pair. /// + [SupportedOSPlatform("windows")] public RSACng() : this(2048) { @@ -27,6 +25,7 @@ public RSACng() /// /// Size of the key to generate, in bits. /// if is not valid + [SupportedOSPlatform("windows")] public RSACng(int keySize) { // Set the property directly so that it gets validated against LegalKeySizes. @@ -74,7 +73,4 @@ private void ForceSetKeySize(int newKeySize) KeySizeValue = newKeySize; } } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs index def40a8d5685a9..e87f36e6a0d9d4 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs @@ -5,32 +5,34 @@ using System.Diagnostics; using System.Formats.Asn1; using System.IO; +using System.Runtime.Versioning; using System.Security.Cryptography.Asn1; using Microsoft.Win32.SafeHandles; using Internal.Cryptography; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - public partial class RSA : AsymmetricAlgorithm - { - public static new partial RSA Create() => new RSAImplementation.RSAOpenSsl(); - } - - internal static partial class RSAImplementation - { -#endif public sealed partial class RSAOpenSsl : RSA { private const int BitsPerByte = 8; private Lazy _key; + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public RSAOpenSsl() : this(2048) { } + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public RSAOpenSsl(int keySize) { ThrowIfNotSupported(); @@ -710,13 +712,7 @@ private void ThrowIfDisposed() { if (_key == null) { - throw new ObjectDisposedException( -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - nameof(RSA) -#else - nameof(RSAOpenSsl) -#endif - ); + throw new ObjectDisposedException(nameof(RSAOpenSsl)); } } @@ -939,7 +935,4 @@ private static void ValidatePadding(RSASignaturePadding padding) private static Exception PaddingModeNotSupported() => new CryptographicException(SR.Cryptography_InvalidPaddingMode); } -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - } -#endif } diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSASecurityTransforms.cs b/src/libraries/Common/src/System/Security/Cryptography/RSASecurityTransforms.cs index 190c7e4d53c9e2..36c8e026f5d4e9 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSASecurityTransforms.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSASecurityTransforms.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.Formats.Asn1; using System.IO; -using System.Numerics; using System.Runtime.InteropServices; using System.Security.Cryptography.Apple; using System.Security.Cryptography.Asn1; @@ -13,16 +12,6 @@ namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - public partial class RSA : AsymmetricAlgorithm - { - public static new partial RSA Create() - { - return new RSAImplementation.RSASecurityTransforms(); - } - } -#endif - internal static partial class RSAImplementation { public sealed partial class RSASecurityTransforms : RSA @@ -632,27 +621,27 @@ private static Interop.AppleCrypto.PAL_HashAlgorithm PalAlgorithmFromAlgorithmNa { if (hashAlgorithmName == HashAlgorithmName.MD5) { - hashSizeInBytes = 128 >> 3; + hashSizeInBytes = MD5.HashSizeInBytes; return Interop.AppleCrypto.PAL_HashAlgorithm.Md5; } else if (hashAlgorithmName == HashAlgorithmName.SHA1) { - hashSizeInBytes = 160 >> 3; + hashSizeInBytes = SHA1.HashSizeInBytes; return Interop.AppleCrypto.PAL_HashAlgorithm.Sha1; } else if (hashAlgorithmName == HashAlgorithmName.SHA256) { - hashSizeInBytes = 256 >> 3; + hashSizeInBytes = SHA256.HashSizeInBytes; return Interop.AppleCrypto.PAL_HashAlgorithm.Sha256; } else if (hashAlgorithmName == HashAlgorithmName.SHA384) { - hashSizeInBytes = 384 >> 3; + hashSizeInBytes = SHA384.HashSizeInBytes; return Interop.AppleCrypto.PAL_HashAlgorithm.Sha384; } else if (hashAlgorithmName == HashAlgorithmName.SHA512) { - hashSizeInBytes = 512 >> 3; + hashSizeInBytes = SHA512.HashSizeInBytes; return Interop.AppleCrypto.PAL_HashAlgorithm.Sha512; } diff --git a/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs index 092c33aa32b903..ee58a16f4436eb 100644 --- a/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs +++ b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs @@ -96,11 +96,11 @@ public override string TestsResultsFinalPath { get { - string? publicDir = Environment.GetEnvironmentVariable("DOCSDIR"); - if (string.IsNullOrEmpty(publicDir)) - throw new ArgumentException("DOCSDIR should not be empty"); + string? testResultsDir = Environment.GetEnvironmentVariable("TEST_RESULTS_DIR"); + if (string.IsNullOrEmpty(testResultsDir)) + throw new ArgumentException("TEST_RESULTS_DIR should not be empty"); - return Path.Combine(publicDir, "testResults.xml"); + return Path.Combine(testResultsDir, "testResults.xml"); } } } diff --git a/src/libraries/Common/tests/System/IO/Compression/ZipTestHelper.cs b/src/libraries/Common/tests/System/IO/Compression/ZipTestHelper.cs index 6f319461c35ef4..b5937a946869e3 100644 --- a/src/libraries/Common/tests/System/IO/Compression/ZipTestHelper.cs +++ b/src/libraries/Common/tests/System/IO/Compression/ZipTestHelper.cs @@ -383,5 +383,69 @@ internal static void AddEntry(ZipArchive archive, string name, string contents, w.WriteLine(contents); } } + + protected const string Utf8SmileyEmoji = "\ud83d\ude04"; + protected const string Utf8LowerCaseOUmlautChar = "\u00F6"; + protected const string Utf8CopyrightChar = "\u00A9"; + protected const string AsciiFileName = "file.txt"; + // The o with umlaut is a character that exists in both latin1 and utf8 + protected const string Utf8AndLatin1FileName = $"{Utf8LowerCaseOUmlautChar}.txt"; + // emojis only make sense in utf8 + protected const string Utf8FileName = $"{Utf8SmileyEmoji}.txt"; + protected static readonly string ALettersUShortMaxValueMinusOne = new string('a', ushort.MaxValue - 1); + protected static readonly string ALettersUShortMaxValue = ALettersUShortMaxValueMinusOne + 'a'; + protected static readonly string ALettersUShortMaxValueMinusOneAndCopyRightChar = ALettersUShortMaxValueMinusOne + Utf8CopyrightChar; + protected static readonly string ALettersUShortMaxValueMinusOneAndTwoCopyRightChars = ALettersUShortMaxValueMinusOneAndCopyRightChar + Utf8CopyrightChar; + + // Returns pairs that are returned the same way by Utf8 and Latin1 + // Returns: originalComment, expectedComment + private static IEnumerable SharedComment_Data() + { + yield return new object[] { null, string.Empty }; + yield return new object[] { string.Empty, string.Empty }; + yield return new object[] { "a", "a" }; + yield return new object[] { Utf8LowerCaseOUmlautChar, Utf8LowerCaseOUmlautChar }; + } + + // Returns pairs as expected by Utf8 + // Returns: originalComment, expectedComment + public static IEnumerable Utf8Comment_Data() + { + string asciiOriginalOverMaxLength = ALettersUShortMaxValue + "aaa"; + + // A smiley emoji code point consists of two characters, + // meaning the whole emoji should be fully truncated + string utf8OriginalALettersAndOneEmojiDoesNotFit = ALettersUShortMaxValueMinusOne + Utf8SmileyEmoji; + + // A smiley emoji code point consists of two characters, + // so it should not be truncated if it's the last character and the total length is not over the limit. + string utf8OriginalALettersAndOneEmojiFits = "aaaaa" + Utf8SmileyEmoji; + + yield return new object[] { asciiOriginalOverMaxLength, ALettersUShortMaxValue }; + yield return new object[] { utf8OriginalALettersAndOneEmojiDoesNotFit, ALettersUShortMaxValueMinusOne }; + yield return new object[] { utf8OriginalALettersAndOneEmojiFits, utf8OriginalALettersAndOneEmojiFits }; + + foreach (object[] e in SharedComment_Data()) + { + yield return e; + } + } + + // Returns pairs as expected by Latin1 + // Returns: originalComment, expectedComment + public static IEnumerable Latin1Comment_Data() + { + // In Latin1, all characters are exactly 1 byte + + string latin1ExpectedALettersAndOneOUmlaut = ALettersUShortMaxValueMinusOne + Utf8LowerCaseOUmlautChar; + string latin1OriginalALettersAndTwoOUmlauts = latin1ExpectedALettersAndOneOUmlaut + Utf8LowerCaseOUmlautChar; + + yield return new object[] { latin1OriginalALettersAndTwoOUmlauts, latin1ExpectedALettersAndOneOUmlaut }; + + foreach (object[] e in SharedComment_Data()) + { + yield return e; + } + } } } diff --git a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs index 9a523ca701417e..5407a6095cd0ab 100644 --- a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs @@ -86,6 +86,17 @@ public void Close() CloseWebSocket(); } + public async Task WaitForCloseAsync(CancellationToken cancellationToken) + { + while (_websocket != null + ? _websocket.State != WebSocketState.Closed + : !(_socket.Poll(1, SelectMode.SelectRead) && _socket.Available == 0)) + { + cancellationToken.ThrowIfCancellationRequested(); + await Task.Delay(100); + } + } + public void Shutdown(SocketShutdown how) { _socket?.Shutdown(how); @@ -138,6 +149,9 @@ public abstract class GenericLoopbackConnection : IDisposable /// Waits for the client to signal cancellation. public abstract Task WaitForCancellationAsync(bool ignoreIncomingData = true); + /// Waits for the client to signal cancellation. + public abstract Task WaitForCloseAsync(CancellationToken cancellationToken); + /// Helper function to make it easier to convert old test with strings. public async Task SendResponseBodyAsync(string content, bool isFinal = true) { diff --git a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs index b3bb701e540f36..2329475728c67b 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnection.cs @@ -984,5 +984,10 @@ public override async Task WaitForCancellationAsync(bool ignoreIncomingData = tr RstStreamFrame rstStreamFrame = Assert.IsType(frame); Assert.Equal((int)ProtocolErrors.CANCEL, rstStreamFrame.ErrorCode); } + + public override Task WaitForCloseAsync(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } } } diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index ceb36e0bcbfb12..78c49a1aaee13d 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Net.Http.Functional.Tests; using Xunit; +using System.Threading; namespace System.Net.Test.Common { @@ -305,6 +306,11 @@ public override async Task WaitForCancellationAsync(bool ignoreIncomingData = tr { await GetOpenRequest().WaitForCancellationAsync(ignoreIncomingData).ConfigureAwait(false); } + + public override Task WaitForCloseAsync(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } } } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs index 7ae59fe98e54d2..a363553ba598eb 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -28,6 +28,7 @@ public HttpClientHandler_Cancellation_Test(ITestOutputHelper output) : base(outp [Theory] [InlineData(false, CancellationMode.Token)] [InlineData(true, CancellationMode.Token)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/36634", TestPlatforms.Browser)] // out of memory public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(bool chunkedTransfer, CancellationMode mode) { if (LoopbackServerFactory.Version >= HttpVersion20.Value && chunkedTransfer) @@ -228,10 +229,21 @@ await LoopbackServerFactory.CreateServerAsync(async (server, url) => await connection.ReadRequestDataAsync(); await connection.SendResponseAsync(HttpStatusCode.OK, headers: headers, isFinal: false); await clientFinished.Task; + +#if TARGET_BROWSER + // make sure that the browser closed the connection + await connection.WaitForCloseAsync(CancellationToken.None); +#endif }); var req = new HttpRequestMessage(HttpMethod.Get, url) { Version = UseVersion }; req.Headers.ConnectionClose = connectionClose; + +#if TARGET_BROWSER + var WebAssemblyEnableStreamingResponseKey = new HttpRequestOptionsKey("WebAssemblyEnableStreamingResponse"); + req.Options.Set(WebAssemblyEnableStreamingResponseKey, true); +#endif + Task getResponse = client.SendAsync(TestAsync, req, HttpCompletionOption.ResponseHeadersRead, cts.Token); await ValidateClientCancellationAsync(async () => { @@ -247,7 +259,6 @@ await ValidateClientCancellationAsync(async () => cts.Cancel(); await readTask; }); - try { clientFinished.SetResult(true); @@ -256,11 +267,13 @@ await ValidateClientCancellationAsync(async () => }); } } + [Theory] [InlineData(CancellationMode.CancelPendingRequests, false)] [InlineData(CancellationMode.DisposeHttpClient, false)] [InlineData(CancellationMode.CancelPendingRequests, true)] [InlineData(CancellationMode.DisposeHttpClient, true)] + [SkipOnPlatform(TestPlatforms.Browser, "Browser doesn't have blocking synchronous Stream.ReadByte and so it waits for whole body")] public async Task GetAsync_CancelPendingRequests_DoesntCancelReadAsyncOnResponseStream(CancellationMode mode, bool copyToAsync) { if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) diff --git a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs index 30cb5d4a3f0431..70ddfcf1f5aaf6 100644 --- a/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs @@ -1065,6 +1065,11 @@ public override async Task WaitForCancellationAsync(bool ignoreIncomingData = tr } } } + + public override Task WaitForCloseAsync(CancellationToken cancellationToken) + { + return _socket.WaitForCloseAsync(cancellationToken); + } } public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/RemoteLoopServer/Handlers/RemoteLoopHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/RemoteLoopServer/Handlers/RemoteLoopHandler.cs index 4f83c67b0b30f4..557eaa494f7c78 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/RemoteLoopServer/Handlers/RemoteLoopHandler.cs +++ b/src/libraries/Common/tests/System/Net/Prerequisites/RemoteLoopServer/Handlers/RemoteLoopHandler.cs @@ -100,6 +100,11 @@ private static async Task ProcessWebSocketRequest(HttpContext context, WebSocket var slice = new ArraySegment(testedBuffer, 0, testedNext.Result); await control.SendAsync(slice, WebSocketMessageType.Binary, true, cts.Token).ConfigureAwait(false); } + // did we get TCP FIN? + if (!close && (tested.Poll(1, SelectMode.SelectRead) && tested.Available == 0)) + { + close = true; + } if (!close) { testedNext = tested.ReceiveAsync(new Memory(testedBuffer), SocketFlags.None, cts.Token).AsTask(); @@ -142,14 +147,14 @@ private static async Task ProcessWebSocketRequest(HttpContext context, WebSocket } catch (WebSocketException ex) { - logger.LogWarning("ProcessWebSocketRequest closing failed", ex); + logger.LogWarning("RemoteLoopHandler.ProcessWebSocketRequest closing failed", ex); } } cts.Cancel(); } catch (Exception ex) { - logger.LogError("ProcessWebSocketRequest failed", ex); + logger.LogError("RemoteLoopHandler.ProcessWebSocketRequest failed", ex); } finally { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs index 689e1391cb3eed..1afcb2cbf977d8 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs @@ -411,6 +411,7 @@ public void ReadWriteSect163k1Key1SubjectPublicKeyInfo() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64446", typeof(PlatformSupport), nameof(PlatformSupport.IsAndroidVersionAtLeast31))] public void ReadWriteSect163k1Key1ExplicitECPrivateKey() { ReadWriteBase64ECPrivateKey( @@ -425,6 +426,7 @@ public void ReadWriteSect163k1Key1ExplicitECPrivateKey() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64446", typeof(PlatformSupport), nameof(PlatformSupport.IsAndroidVersionAtLeast31))] public void ReadWriteSect163k1Key1ExplicitPkcs8() { ReadWriteBase64Pkcs8( @@ -439,6 +441,7 @@ public void ReadWriteSect163k1Key1ExplicitPkcs8() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64446", typeof(PlatformSupport), nameof(PlatformSupport.IsAndroidVersionAtLeast31))] public void ReadWriteSect163k1Key1ExplicitEncryptedPkcs8() { ReadWriteBase64EncryptedPkcs8( @@ -459,6 +462,7 @@ public void ReadWriteSect163k1Key1ExplicitEncryptedPkcs8() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64446", typeof(PlatformSupport), nameof(PlatformSupport.IsAndroidVersionAtLeast31))] public void ReadWriteSect163k1Key1ExplicitSubjectPublicKeyInfo() { ReadWriteBase64SubjectPublicKeyInfo( @@ -578,6 +582,7 @@ public void ReadWriteC2pnb163v1SubjectPublicKeyInfo() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64446", typeof(PlatformSupport), nameof(PlatformSupport.IsAndroidVersionAtLeast31))] public void ReadWriteC2pnb163v1ExplicitECPrivateKey() { ReadWriteBase64ECPrivateKey( @@ -593,6 +598,7 @@ public void ReadWriteC2pnb163v1ExplicitECPrivateKey() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64446", typeof(PlatformSupport), nameof(PlatformSupport.IsAndroidVersionAtLeast31))] public void ReadWriteC2pnb163v1ExplicitPkcs8() { ReadWriteBase64Pkcs8( @@ -608,6 +614,7 @@ public void ReadWriteC2pnb163v1ExplicitPkcs8() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64446", typeof(PlatformSupport), nameof(PlatformSupport.IsAndroidVersionAtLeast31))] public void ReadWriteC2pnb163v1ExplicitEncryptedPkcs8() { ReadWriteBase64EncryptedPkcs8( @@ -629,6 +636,7 @@ public void ReadWriteC2pnb163v1ExplicitEncryptedPkcs8() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64446", typeof(PlatformSupport), nameof(PlatformSupport.IsAndroidVersionAtLeast31))] public void ReadWriteC2pnb163v1ExplicitSubjectPublicKeyInfo() { ReadWriteBase64SubjectPublicKeyInfo( diff --git a/src/libraries/Common/tests/System/Security/Cryptography/PlatformSupport.cs b/src/libraries/Common/tests/System/Security/Cryptography/PlatformSupport.cs index ce6b9e8d831625..1cf7270f3b7f73 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/PlatformSupport.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/PlatformSupport.cs @@ -17,5 +17,11 @@ internal static class PlatformSupport // Whether or not the current platform supports RC2 internal static readonly bool IsRC2Supported = !PlatformDetection.IsAndroid; + +#if NETCOREAPP + internal static readonly bool IsAndroidVersionAtLeast31 = OperatingSystem.IsAndroidVersionAtLeast(31); +#else + internal static readonly bool IsAndroidVersionAtLeast31 = false; +#endif } } diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index db1af4f4fba6d9..b35772c86df672 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -51,6 +51,7 @@ public static partial class PlatformDetection public static bool IsNotArm64Process => !IsArm64Process; public static bool IsArmOrArm64Process => IsArmProcess || IsArm64Process; public static bool IsNotArmNorArm64Process => !IsArmOrArm64Process; + public static bool IsArmv6Process => (int)RuntimeInformation.ProcessArchitecture == 7; // Architecture.Armv6 public static bool IsX86Process => RuntimeInformation.ProcessArchitecture == Architecture.X86; public static bool IsNotX86Process => !IsX86Process; public static bool IsArgIteratorSupported => IsMonoRuntime || (IsWindows && IsNotArmProcess && !IsNativeAot); diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index a5cc7f68250084..7858515cfc41de 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -23,8 +23,6 @@ net462;net47;net471;net472 - - true @@ -78,11 +76,6 @@ false false - - false diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 89636077e7ca7a..c6bb21939404be 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -120,11 +120,14 @@ - + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/NuGet.config b/src/libraries/Microsoft.Extensions.Configuration.Xml/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration/NuGet.config b/src/libraries/Microsoft.Extensions.Configuration/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/Microsoft.Extensions.Configuration/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/NuGet.config b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs index 69f87fdcd48f6c..3b4646df23a666 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs @@ -86,7 +86,7 @@ namespace {lc.Namespace} // loop until you find top level nested class while (parent != null) { - parentClasses.Add($"partial {parent.Keyword} {parent.Name} {parent.Constraints}"); + parentClasses.Add($"partial {parent.Keyword} {parent.Name}"); parent = parent.ParentClass; } @@ -100,7 +100,7 @@ namespace {lc.Namespace} } _builder.Append($@" - {nestedIndentation}partial {lc.Keyword} {lc.Name} {lc.Constraints} + {nestedIndentation}partial {lc.Keyword} {lc.Name} {nestedIndentation}{{"); foreach (LoggerMethod lm in lc.Methods) @@ -138,14 +138,14 @@ private void GenStruct(LoggerMethod lm, string nestedIndentation) {nestedIndentation}/// {s_generatedTypeSummary} {nestedIndentation}[{s_generatedCodeAttribute}] {nestedIndentation}[{s_editorBrowsableAttribute}] - {nestedIndentation}private readonly struct __{lm.Name}Struct : global::System.Collections.Generic.IReadOnlyList> + {nestedIndentation}private readonly struct __{lm.UniqueName}Struct : global::System.Collections.Generic.IReadOnlyList> {nestedIndentation}{{"); GenFields(lm, nestedIndentation); if (lm.TemplateParameters.Count > 0) { _builder.Append($@" - {nestedIndentation}public __{lm.Name}Struct("); + {nestedIndentation}public __{lm.UniqueName}Struct("); GenArguments(lm); _builder.Append($@") {nestedIndentation}{{"); @@ -166,7 +166,7 @@ private void GenStruct(LoggerMethod lm, string nestedIndentation) {nestedIndentation}}} "); _builder.Append($@" - {nestedIndentation}public static readonly global::System.Func<__{lm.Name}Struct, global::System.Exception?, string> Format = (state, ex) => state.ToString(); + {nestedIndentation}public static readonly global::System.Func<__{lm.UniqueName}Struct, global::System.Exception?, string> Format = (state, ex) => state.ToString(); {nestedIndentation}public int Count => {lm.TemplateParameters.Count + 1}; @@ -206,7 +206,7 @@ private void GenFieldAssignments(LoggerMethod lm, string nestedIndentation) { foreach (LoggerParameter p in lm.TemplateParameters) { - _builder.AppendLine($" {nestedIndentation}this._{p.Name} = {p.Name};"); + _builder.AppendLine($" {nestedIndentation}this._{p.Name} = {p.CodeName};"); } } @@ -265,7 +265,7 @@ private void GenCallbackArguments(LoggerMethod lm) { foreach (LoggerParameter p in lm.TemplateParameters) { - _builder.Append($"{p.Name}, "); + _builder.Append($"{p.CodeName}, "); } } @@ -319,7 +319,11 @@ private void GenParameters(LoggerMethod lm) _builder.Append(", "); } - _builder.Append($"{p.Type} {p.Name}"); + if (p.Qualifier != null) + { + _builder.Append($"{p.Qualifier} "); + } + _builder.Append($"{p.Type} {p.CodeName}"); } } @@ -337,13 +341,13 @@ private void GenArguments(LoggerMethod lm) _builder.Append(", "); } - _builder.Append($"{p.Type} {p.Name}"); + _builder.Append($"{p.Type} {p.CodeName}"); } } private void GenHolder(LoggerMethod lm) { - string typeName = $"__{lm.Name}Struct"; + string typeName = $"__{lm.UniqueName}Struct"; _builder.Append($"new {typeName}("); foreach (LoggerParameter p in lm.TemplateParameters) @@ -353,7 +357,7 @@ private void GenHolder(LoggerMethod lm) _builder.Append(", "); } - _builder.Append(p.Name); + _builder.Append(p.CodeName); } _builder.Append(')'); @@ -375,7 +379,7 @@ private void GenLogMethod(LoggerMethod lm, string nestedIndentation) GenDefineTypes(lm, brackets: false); - _builder.Append($@"global::System.Exception?> __{lm.Name}Callback = + _builder.Append($@"global::System.Exception?> __{lm.UniqueName}Callback = {nestedIndentation}global::Microsoft.Extensions.Logging.LoggerMessage.Define"); GenDefineTypes(lm, brackets: true); @@ -404,7 +408,7 @@ private void GenLogMethod(LoggerMethod lm, string nestedIndentation) if (UseLoggerMessageDefine(lm)) { _builder.Append($@" - {nestedIndentation}{enabledCheckIndentation}__{lm.Name}Callback({logger}, "); + {nestedIndentation}{enabledCheckIndentation}__{lm.UniqueName}Callback({logger}, "); GenCallbackArguments(lm); @@ -420,7 +424,7 @@ private void GenLogMethod(LoggerMethod lm, string nestedIndentation) GenHolder(lm); _builder.Append($@", {nestedIndentation}{enabledCheckIndentation}{exceptionArg}, - {nestedIndentation}{enabledCheckIndentation}__{lm.Name}Struct.Format);"); + {nestedIndentation}{enabledCheckIndentation}__{lm.UniqueName}Struct.Format);"); } if (!lm.SkipEnabledCheck) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs index 2f624f6cec974e..22ee4d13ef1caf 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs @@ -306,6 +306,15 @@ public IReadOnlyList GetLogClasses(IEnumerable 0) + { + ParameterSyntax paramSyntax = paramSymbol.DeclaringSyntaxReferences[0].GetSyntax(_cancellationToken) as ParameterSyntax; + if (paramSyntax != null && !string.IsNullOrEmpty(paramSyntax.Identifier.Text)) + { + needsAtSign = paramSyntax.Identifier.Text[0] == '@'; + } + } if (string.IsNullOrWhiteSpace(paramName)) { // semantic problem, just bail quietly @@ -321,6 +330,15 @@ public IReadOnlyList GetLogClasses(IEnumerable GetLogClasses(IEnumerable Keyword = parentLoggerClass.Keyword.ValueText, Namespace = nspace, Name = parentLoggerClass.Identifier.ToString() + parentLoggerClass.TypeParameterList, - Constraints = parentLoggerClass.ConstraintClauses.ToString(), ParentClass = null, }; @@ -514,6 +532,23 @@ bool IsAllowedKind(SyntaxKind kind) => if (lc != null) { + //once we've collected all methods for the given class, check for overloads + //and provide unique names for logger methods + var methods = new Dictionary(lc.Methods.Count); + foreach (LoggerMethod lm in lc.Methods) + { + if (methods.ContainsKey(lm.Name)) + { + int currentCount = methods[lm.Name]; + lm.UniqueName = $"{lm.Name}{currentCount}"; + methods[lm.Name] = currentCount + 1; + } + else + { + lm.UniqueName = lm.Name; + methods[lm.Name] = 1; //start from 1 + } + } results.Add(lc); } } @@ -683,7 +718,6 @@ internal class LoggerClass public string Keyword = string.Empty; public string Namespace = string.Empty; public string Name = string.Empty; - public string Constraints = string.Empty; public LoggerClass? ParentClass; } @@ -697,6 +731,7 @@ internal class LoggerMethod public readonly Dictionary TemplateMap = new(StringComparer.OrdinalIgnoreCase); public readonly List TemplateList = new(); public string Name = string.Empty; + public string UniqueName = string.Empty; public string Message = string.Empty; public int? Level; public int EventId; @@ -714,6 +749,8 @@ internal class LoggerParameter { public string Name = string.Empty; public string Type = string.Empty; + public string CodeName = string.Empty; + public string? Qualifier; public bool IsLogger; public bool IsException; public bool IsLogLevel; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDefaultValues.generated.txt b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDefaultValues.generated.txt index 5292db82ac8c84..9fafdd9774b0da 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDefaultValues.generated.txt +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDefaultValues.generated.txt @@ -3,7 +3,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses { - partial class TestWithDefaultValues + partial class TestWithDefaultValues { /// This API supports the logging infrastructure and is not intended to be used directly from your code. It is subject to change in the future. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDynamicLogLevel.generated.txt b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDynamicLogLevel.generated.txt index 6326923544aa9e..2717a073492c05 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDynamicLogLevel.generated.txt +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithDynamicLogLevel.generated.txt @@ -3,7 +3,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses { - partial class TestWithDynamicLogLevel + partial class TestWithDynamicLogLevel { /// This API supports the logging infrastructure and is not intended to be used directly from your code. It is subject to change in the future. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithMoreThan6Params.generated.txt b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithMoreThan6Params.generated.txt index 84611c6766f720..0b851e5acd0047 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithMoreThan6Params.generated.txt +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithMoreThan6Params.generated.txt @@ -3,7 +3,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses { - partial class TestWithMoreThan6Params + partial class TestWithMoreThan6Params { /// This API supports the logging infrastructure and is not intended to be used directly from your code. It is subject to change in the future. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithNestedClass.generated.txt b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithNestedClass.generated.txt index b7b93bf27bd02d..893edde95fa3fc 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithNestedClass.generated.txt +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithNestedClass.generated.txt @@ -3,17 +3,17 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses.NestedNamespace { - partial class MultiLevelNestedClass + partial class MultiLevelNestedClass { - partial struct NestedStruct + partial struct NestedStruct { - partial record NestedRecord + partial record NestedRecord { - partial class NestedClassTestsExtensions where T1 : Class1 + partial class NestedClassTestsExtensions { - partial class NestedMiddleParentClass + partial class NestedMiddleParentClass { - partial class Nested where T2 : Class2 + partial class Nested { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] private static readonly global::System.Action __M9Callback = diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithSkipEnabledCheck.generated.txt b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithSkipEnabledCheck.generated.txt index 24575eb81bf458..8b12047f86455f 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithSkipEnabledCheck.generated.txt +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithSkipEnabledCheck.generated.txt @@ -3,7 +3,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses { - partial class TestWithSkipEnabledCheck + partial class TestWithSkipEnabledCheck { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] private static readonly global::System.Action __M0Callback = diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithTwoParams.generated.txt b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithTwoParams.generated.txt index d7c2482cdd9216..14ffb45b81fa41 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithTwoParams.generated.txt +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithTwoParams.generated.txt @@ -3,7 +3,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses { - partial class TestWithTwoParams + partial class TestWithTwoParams { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")] private static readonly global::System.Action, global::System.Exception?> __M0Callback = diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs index eda529fade4ef1..59c5965fefef36 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs @@ -3,8 +3,12 @@ using System; using System.Collections.Generic; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Generators.Tests.TestClasses; +using Microsoft.Extensions.Logging.Generators.Tests.TestClasses.UsesConstraintInAnotherNamespace; using Xunit; +using NamespaceForABC; +using ConstraintInAnotherNamespace; namespace Microsoft.Extensions.Logging.Generators.Tests { @@ -430,6 +434,71 @@ public void SkipEnabledCheckTests() Assert.Equal(1, logger.CallCount); Assert.Equal("LoggerMethodWithTrueSkipEnabledCheck", logger.LastEventId.Name); } + private struct MyStruct { } + + [Fact] + public void ConstraintsTests() + { + var logger = new MockLogger(); + + var printer = new MessagePrinter(); + logger.Reset(); + printer.Print(logger, new Message() { Text = "Hello" }); + Assert.Equal(LogLevel.Information, logger.LastLogLevel); + Assert.Null(logger.LastException); + Assert.Equal("The message is Hello.", logger.LastFormattedString); + Assert.Equal(1, logger.CallCount); + + var printer2 = new MessagePrinterHasConstraintOnLogClassAndLogMethod(); + logger.Reset(); + printer2.Print(logger, new Message() { Text = "Hello" }); + Assert.Equal(LogLevel.Information, logger.LastLogLevel); + Assert.Null(logger.LastException); + Assert.Equal("The message is `Hello`.", logger.LastFormattedString); + Assert.Equal(1, logger.CallCount); + + logger.Reset(); + ConstraintsTestExtensions.M0(logger, 12); + Assert.Equal(LogLevel.Debug, logger.LastLogLevel); + Assert.Null(logger.LastException); + Assert.Equal("M012", logger.LastFormattedString); + Assert.Equal(1, logger.CallCount); + + logger.Reset(); + ConstraintsTestExtensions1.M0(logger, 12); + Assert.Equal(LogLevel.Debug, logger.LastLogLevel); + Assert.Null(logger.LastException); + Assert.Equal("M012", logger.LastFormattedString); + Assert.Equal(1, logger.CallCount); + + logger.Reset(); + ConstraintsTestExtensions2.M0(logger, 12); + Assert.Equal(LogLevel.Debug, logger.LastLogLevel); + Assert.Null(logger.LastException); + Assert.Equal("M012", logger.LastFormattedString); + Assert.Equal(1, logger.CallCount); + + logger.Reset(); + ConstraintsTestExtensions3.M0(logger, 12); + Assert.Equal(LogLevel.Debug, logger.LastLogLevel); + Assert.Null(logger.LastException); + Assert.Equal("M012", logger.LastFormattedString); + Assert.Equal(1, logger.CallCount); + + logger.Reset(); + ConstraintsTestExtensions4.M0(logger, 12); + Assert.Equal(LogLevel.Debug, logger.LastLogLevel); + Assert.Null(logger.LastException); + Assert.Equal("M012", logger.LastFormattedString); + Assert.Equal(1, logger.CallCount); + + logger.Reset(); + ConstraintsTestExtensions5.M0(logger, 12); + Assert.Equal(LogLevel.Debug, logger.LastLogLevel); + Assert.Null(logger.LastException); + Assert.Equal("M012", logger.LastFormattedString); + Assert.Equal(1, logger.CallCount); + } [Fact] public void NestedClassTests() @@ -518,6 +587,26 @@ public void TemplateTests() } + [Fact] + public void OverloadTests() + { + var logger = new MockLogger(); + + logger.Reset(); + OverloadTestExtensions.M0(logger, 1); + Assert.Null(logger.LastException); + Assert.Equal($"{nameof(OverloadTestExtensions.M0)}1", logger.LastFormattedString); + Assert.Equal(LogLevel.Trace, logger.LastLogLevel); + Assert.Equal("M0", logger.LastEventId.Name); + + logger.Reset(); + OverloadTestExtensions.M0(logger, "string"); + Assert.Null(logger.LastException); + Assert.Equal($"{nameof(OverloadTestExtensions.M0)}string", logger.LastFormattedString); + Assert.Equal(LogLevel.Trace, logger.LastLogLevel); + Assert.Equal("M0", logger.LastEventId.Name); + } + private static void AssertLastState(MockLogger logger, params KeyValuePair[] expected) { var rol = (IReadOnlyList>)logger.LastState!; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs index 4697e5603cd0f5..05a7999c83c59d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs @@ -616,6 +616,21 @@ partial class C Assert.Equal(DiagnosticDescriptors.LoggingMethodIsGeneric.Id, diagnostics[0].Id); } + [Theory] + [InlineData("ref")] + [InlineData("in")] + public async Task SupportsRefKindsInAndRef(string modifier) + { + IReadOnlyList diagnostics = await RunGenerator(@$" + partial class C + {{ + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""Parameter {{P1}}"")] + static partial void M(ILogger logger, {modifier} int p1); + }}"); + + Assert.Empty(diagnostics); + } + [Fact] public async Task Templates() { diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/AtSymbolTestExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/AtSymbolTestExtensions.cs new file mode 100644 index 00000000000000..be41f22e5a73a5 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/AtSymbolTestExtensions.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses +{ + internal static partial class AtSymbolTestExtensions + { + [LoggerMessage(EventId = 0, Level = LogLevel.Information, Message = "M0 {event}")] + internal static partial void M0(ILogger logger, string @event); + } +} \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/ConstaintsTestExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/ConstaintsTestExtensions.cs new file mode 100644 index 00000000000000..7e6f87271b535f --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/ConstaintsTestExtensions.cs @@ -0,0 +1,118 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses +{ + using ConstraintInAnotherNamespace; + namespace UsesConstraintInAnotherNamespace + { + public partial class MessagePrinter + where T : Message + { + public void Print(ILogger logger, T message) + { + Log.Message(logger, message.Text); + } + + internal static partial class Log + { + [LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "The message is {Text}.")] + internal static partial void Message(ILogger logger, string? text); + } + } + + public partial class MessagePrinterHasConstraintOnLogClassAndLogMethod + where T : Message + { + public void Print(ILogger logger, T message) + { + Log.Message(logger, message); + } + + internal static partial class Log where U : Message + { + [LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "The message is {Text}.")] + internal static partial void Message(ILogger logger, U text); + } + } + } + + internal static partial class ConstraintsTestExtensions + where T : class + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = "M0{p0}")] + public static partial void M0(ILogger logger, int p0); + + public static void Foo(T dummy) + { + } + } + + internal static partial class ConstraintsTestExtensions1 + where T : struct + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = "M0{p0}")] + public static partial void M0(ILogger logger, int p0); + + public static void Foo(T dummy) + { + } + } + + internal static partial class ConstraintsTestExtensions2 + where T : unmanaged + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = "M0{p0}")] + public static partial void M0(ILogger logger, int p0); + + public static void Foo(T dummy) + { + } + } + + internal static partial class ConstraintsTestExtensions3 + where T : new() + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = "M0{p0}")] + public static partial void M0(ILogger logger, int p0); + + public static void Foo(T dummy) + { + } + } + + internal static partial class ConstraintsTestExtensions4 + where T : System.Attribute + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = "M0{p0}")] + public static partial void M0(ILogger logger, int p0); + + public static void Foo(T dummy) + { + } + } + + internal static partial class ConstraintsTestExtensions5 + where T : notnull + { + [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = "M0{p0}")] + public static partial void M0(ILogger logger, int p0); + + public static void Foo(T dummy) + { + } + } +} + +namespace ConstraintInAnotherNamespace +{ + public class Message + { + public string? Text { get; set; } + + public override string ToString() + { + return $"`{Text}`"; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/NestedClassTestsExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/NestedClassTestsExtensions.cs index 4b5b6cdbf90a26..ba6b87f6d5308a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/NestedClassTestsExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/NestedClassTestsExtensions.cs @@ -3,6 +3,8 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses { + using NamespaceForABC; + internal static partial class NestedClassTestsExtensions where T : ABC { internal static partial class NestedMiddleParentClass @@ -26,7 +28,6 @@ internal static partial class NestedClass } } } - public class ABC {} public partial struct NestedStruct { @@ -61,3 +62,8 @@ internal static partial class Logger } } } + +namespace NamespaceForABC +{ + public class ABC {} +} \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/OverloadTestExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/OverloadTestExtensions.cs new file mode 100644 index 00000000000000..e0c84fcebedd02 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/OverloadTestExtensions.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses +{ + internal static partial class OverloadTestExtensions + { + [LoggerMessage(EventId = 0, Level = LogLevel.Trace, Message = "M0{p0}")] + public static partial void M0(ILogger logger, int p0); + + [LoggerMessage(EventId = 1, Level = LogLevel.Trace, Message = "M0{p0}")] + public static partial void M0(ILogger logger, string p0); + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/ParameterTestExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/ParameterTestExtensions.cs new file mode 100644 index 00000000000000..f51fc2e62f6a96 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/ParameterTestExtensions.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses +{ + internal static partial class ParameterTestExtensions + { + internal struct S + { + public override string ToString() => "Hello from S"; + } + + [LoggerMessage(EventId = 0, Level = LogLevel.Information, Message = "UseInParameter {s}")] + internal static partial void UseInParameter(ILogger logger, in S s); + + [LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "UseRefParameter {s}")] + internal static partial void UseRefParameter(ILogger logger, ref S s); + } +} diff --git a/src/libraries/Microsoft.NETCore.Platforms/src/Directory.Build.props b/src/libraries/Microsoft.NETCore.Platforms/src/Directory.Build.props deleted file mode 100644 index ea706165b9f58f..00000000000000 --- a/src/libraries/Microsoft.NETCore.Platforms/src/Directory.Build.props +++ /dev/null @@ -1,6 +0,0 @@ - - - false - - - \ No newline at end of file diff --git a/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj b/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj index 1351a67f30f3e0..41d577d5ef9c8e 100644 --- a/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj +++ b/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj @@ -1,6 +1,7 @@ $(NetCoreAppToolCurrent);$(NetFrameworkToolCurrent) + false false Microsoft.NETCore.Platforms.BuildTasks @@ -20,7 +21,7 @@ <_generateRuntimeGraphTargetFramework Condition="'$(MSBuildRuntimeType)' == 'core'">$(NetCoreAppToolCurrent) <_generateRuntimeGraphTargetFramework Condition="'$(MSBuildRuntimeType)' != 'core'">net472 - <_generateRuntimeGraphTask>$([MSBuild]::NormalizePath('$(BaseOutputPath)', '$(_generateRuntimeGraphTargetFramework)-$(Configuration)', '$(AssemblyName).dll')) + <_generateRuntimeGraphTask>$([MSBuild]::NormalizePath('$(BaseOutputPath)', $(Configuration), '$(_generateRuntimeGraphTargetFramework)', '$(AssemblyName).dll')) $(AdditionalRuntimeIdentifiers);$(OutputRID) diff --git a/src/libraries/Microsoft.VisualBasic.Core/NuGet.config b/src/libraries/Microsoft.VisualBasic.Core/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/Microsoft.VisualBasic.Core/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj index d14aa9f72e4075..cdc18e0dd43918 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj +++ b/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft.VisualBasic.Core.vbproj @@ -97,8 +97,8 @@ - + diff --git a/src/libraries/Microsoft.Win32.Primitives/Microsoft.Win32.Primitives.sln b/src/libraries/Microsoft.Win32.Primitives/Microsoft.Win32.Primitives.sln index 011d904181c8bc..f5713d005e2be9 100644 --- a/src/libraries/Microsoft.Win32.Primitives/Microsoft.Win32.Primitives.sln +++ b/src/libraries/Microsoft.Win32.Primitives/Microsoft.Win32.Primitives.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Win32.Primitives" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Win32.Primitives.Tests", "tests\Microsoft.Win32.Primitives.Tests.csproj", "{B43D6BB6-1760-4DB9-87CB-792D42846C62}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{5F4ABB4F-CE69-47B7-860F-40B0DA68A7DB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{5F4ABB4F-CE69-47B7-860F-40B0DA68A7DB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{04266CFA-9B2A-4A22-9FC1-92197EF2A9A9}" EndProject diff --git a/src/libraries/Microsoft.Win32.Registry.AccessControl/NuGet.config b/src/libraries/Microsoft.Win32.Registry.AccessControl/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/Microsoft.Win32.Registry.AccessControl/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj b/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj index fd6384aebd963d..506507556b4437 100644 --- a/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj +++ b/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj @@ -9,7 +9,7 @@ Commonly Used Types: System.Security.AccessControl.RegistryAccessRule System.Security.AccessControl.RegistryAuditRule System.Security.AccessControl.RegistrySecurity - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0-windows;netstandard2.0;$(NetFrameworkMinimum) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) diff --git a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj index 8fbb8dd78854b1..882394c96aac24 100644 --- a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj +++ b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj @@ -72,8 +72,6 @@ - - @@ -84,5 +82,7 @@ + + diff --git a/src/libraries/System.AppContext/System.AppContext.sln b/src/libraries/System.AppContext/System.AppContext.sln index 190f61d161961c..a4cdca4e0e7049 100644 --- a/src/libraries/System.AppContext/System.AppContext.sln +++ b/src/libraries/System.AppContext/System.AppContext.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.AppContext", "src\Sy EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.AppContext.Tests", "tests\System.AppContext.Tests.csproj", "{007AD19C-8A80-4463-834C-BE7AE1808A04}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{1CFA73AC-672E-4EED-8003-51682AF702E5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{1CFA73AC-672E-4EED-8003-51682AF702E5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{68E366F0-A62B-4528-8B26-CDFE17AA9C42}" EndProject diff --git a/src/libraries/System.Buffers/System.Buffers.sln b/src/libraries/System.Buffers/System.Buffers.sln index 467026337e3b8a..e112e283ff47ae 100644 --- a/src/libraries/System.Buffers/System.Buffers.sln +++ b/src/libraries/System.Buffers/System.Buffers.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Buffers", "src\Syste EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Buffers.Tests", "tests\System.Buffers.Tests.csproj", "{FF86CB73-2E54-4E89-9491-258324F291D0}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{AA1510B5-19AF-488B-A390-AFFDA0109571}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{AA1510B5-19AF-488B-A390-AFFDA0109571}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{3EA59DDB-E3E9-4CA0-9FDF-3659C0CD4621}" EndProject diff --git a/src/libraries/System.Collections.Concurrent/System.Collections.Concurrent.sln b/src/libraries/System.Collections.Concurrent/System.Collections.Concurrent.sln index fc0b812d7d2bcf..5e2c1daeeec847 100644 --- a/src/libraries/System.Collections.Concurrent/System.Collections.Concurrent.sln +++ b/src/libraries/System.Collections.Concurrent/System.Collections.Concurrent.sln @@ -13,7 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Collections", "..\Sy EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.Tracing", "..\System.Diagnostics.Tracing\src\System.Diagnostics.Tracing.csproj", "{93FB3527-B9E6-4ECA-8F36-56835F4F9236}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{431D18E4-4464-45C0-BBF2-1834B73E8095}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{431D18E4-4464-45C0-BBF2-1834B73E8095}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{1D4FEFF5-24CC-4725-90CD-651D389C0961}" EndProject diff --git a/src/libraries/System.Collections/System.Collections.sln b/src/libraries/System.Collections/System.Collections.sln index 4ccde2df9a12f3..daaf67b3fab043 100644 --- a/src/libraries/System.Collections/System.Collections.sln +++ b/src/libraries/System.Collections/System.Collections.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Collections", "src\S EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Collections.Tests", "tests\System.Collections.Tests.csproj", "{BB54ED9D-FF71-4D91-B7C0-984AB0976798}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{F2E57833-4968-430D-8149-733DE03A7314}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{F2E57833-4968-430D-8149-733DE03A7314}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{0582BADC-0A09-4DF7-8D8A-9B6763FBE9F3}" EndProject diff --git a/src/libraries/System.Collections/src/System/Collections/BitArray.cs b/src/libraries/System.Collections/src/System/Collections/BitArray.cs index 9f8531a9e818a8..925f175f7fcf8f 100644 --- a/src/libraries/System.Collections/src/System/Collections/BitArray.cs +++ b/src/libraries/System.Collections/src/System/Collections/BitArray.cs @@ -4,9 +4,11 @@ using System.Buffers.Binary; using System.Diagnostics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics.Arm; +using Internal.Runtime.CompilerServices; namespace System.Collections { @@ -145,81 +147,32 @@ public unsafe BitArray(bool[] values) // (true for any non-zero values, false for 0) - any values between 2-255 will be interpreted as false. // Instead, We compare with zeroes (== false) then negate the result to ensure compatibility. - if (Avx2.IsSupported) + ref byte value = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(values)); + + if (Vector256.IsHardwareAccelerated) { - // JIT does not support code hoisting for SIMD yet - Vector256 zero = Vector256.Zero; - fixed (bool* ptr = values) + for (; (i + Vector256ByteCount) <= (uint)values.Length; i += Vector256ByteCount) { - for (; (i + Vector256ByteCount) <= (uint)values.Length; i += Vector256ByteCount) - { - Vector256 vector = Avx.LoadVector256((byte*)ptr + i); - Vector256 isFalse = Avx2.CompareEqual(vector, zero); - int result = Avx2.MoveMask(isFalse); - m_array[i / 32u] = ~result; - } + Vector256 vector = Vector256.LoadUnsafe(ref value, i); + Vector256 isFalse = Vector256.Equals(vector, Vector256.Zero); + + uint result = isFalse.ExtractMostSignificantBits(); + m_array[i / 32u] = (int)(~result); } } - else if (Sse2.IsSupported) + else if (Vector128.IsHardwareAccelerated) { - // JIT does not support code hoisting for SIMD yet - Vector128 zero = Vector128.Zero; - fixed (bool* ptr = values) + for (; (i + Vector128ByteCount * 2u) <= (uint)values.Length; i += Vector128ByteCount * 2u) { - for (; (i + Vector128ByteCount * 2u) <= (uint)values.Length; i += Vector128ByteCount * 2u) - { - Vector128 lowerVector = Sse2.LoadVector128((byte*)ptr + i); - Vector128 lowerIsFalse = Sse2.CompareEqual(lowerVector, zero); - int lowerPackedIsFalse = Sse2.MoveMask(lowerIsFalse); + Vector128 lowerVector = Vector128.LoadUnsafe(ref value, i); + Vector128 lowerIsFalse = Vector128.Equals(lowerVector, Vector128.Zero); + uint lowerResult = lowerIsFalse.ExtractMostSignificantBits(); - Vector128 upperVector = Sse2.LoadVector128((byte*)ptr + i + Vector128.Count); - Vector128 upperIsFalse = Sse2.CompareEqual(upperVector, zero); - int upperPackedIsFalse = Sse2.MoveMask(upperIsFalse); + Vector128 upperVector = Vector128.LoadUnsafe(ref value, i + Vector128ByteCount); + Vector128 upperIsFalse = Vector128.Equals(upperVector, Vector128.Zero); + uint upperResult = upperIsFalse.ExtractMostSignificantBits(); - m_array[i / 32u] = ~((upperPackedIsFalse << 16) | lowerPackedIsFalse); - } - } - } - else if (AdvSimd.Arm64.IsSupported) - { - // JIT does not support code hoisting for SIMD yet - // However comparison against zero can be replaced to cmeq against zero (vceqzq_s8) - // See dotnet/runtime#33972 for details - Vector128 zero = Vector128.Zero; - Vector128 bitMask128 = BitConverter.IsLittleEndian ? - Vector128.Create(0x80402010_08040201).AsByte() : - Vector128.Create(0x01020408_10204080).AsByte(); - - fixed (bool* ptr = values) - { - for (; (i + Vector128ByteCount * 2u) <= (uint)values.Length; i += Vector128ByteCount * 2u) - { - // Same logic as SSE2 path, however we lack MoveMask (equivalent) instruction - // As a workaround, mask out the relevant bit after comparison - // and combine by ORing all of them together (In this case, adding all of them does the same thing) - Vector128 lowerVector = AdvSimd.LoadVector128((byte*)ptr + i); - Vector128 lowerIsFalse = AdvSimd.CompareEqual(lowerVector, zero); - Vector128 bitsExtracted1 = AdvSimd.And(lowerIsFalse, bitMask128); - bitsExtracted1 = AdvSimd.Arm64.AddPairwise(bitsExtracted1, bitsExtracted1); - bitsExtracted1 = AdvSimd.Arm64.AddPairwise(bitsExtracted1, bitsExtracted1); - bitsExtracted1 = AdvSimd.Arm64.AddPairwise(bitsExtracted1, bitsExtracted1); - Vector128 lowerPackedIsFalse = bitsExtracted1.AsInt16(); - - Vector128 upperVector = AdvSimd.LoadVector128((byte*)ptr + i + Vector128.Count); - Vector128 upperIsFalse = AdvSimd.CompareEqual(upperVector, zero); - Vector128 bitsExtracted2 = AdvSimd.And(upperIsFalse, bitMask128); - bitsExtracted2 = AdvSimd.Arm64.AddPairwise(bitsExtracted2, bitsExtracted2); - bitsExtracted2 = AdvSimd.Arm64.AddPairwise(bitsExtracted2, bitsExtracted2); - bitsExtracted2 = AdvSimd.Arm64.AddPairwise(bitsExtracted2, bitsExtracted2); - Vector128 upperPackedIsFalse = bitsExtracted2.AsInt16(); - - int result = AdvSimd.Arm64.ZipLow(lowerPackedIsFalse, upperPackedIsFalse).AsInt32().ToScalar(); - if (!BitConverter.IsLittleEndian) - { - result = BinaryPrimitives.ReverseEndianness(result); - } - m_array[i / 32u] = ~result; - } + m_array[i / 32u] = (int)(~((upperResult << 16) | lowerResult)); } } @@ -400,43 +353,24 @@ public unsafe BitArray And(BitArray value) } uint i = 0; - if (Avx2.IsSupported) - { - fixed (int* leftPtr = thisArray) - fixed (int* rightPtr = valueArray) - { - for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) - { - Vector256 leftVec = Avx.LoadVector256(leftPtr + i); - Vector256 rightVec = Avx.LoadVector256(rightPtr + i); - Avx.Store(leftPtr + i, Avx2.And(leftVec, rightVec)); - } - } - } - else if (Sse2.IsSupported) + + ref int left = ref MemoryMarshal.GetArrayDataReference(thisArray); + ref int right = ref MemoryMarshal.GetArrayDataReference(valueArray); + + if (Vector256.IsHardwareAccelerated) { - fixed (int* leftPtr = thisArray) - fixed (int* rightPtr = valueArray) + for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) { - for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) - { - Vector128 leftVec = Sse2.LoadVector128(leftPtr + i); - Vector128 rightVec = Sse2.LoadVector128(rightPtr + i); - Sse2.Store(leftPtr + i, Sse2.And(leftVec, rightVec)); - } + Vector256 result = Vector256.LoadUnsafe(ref left, i) & Vector256.LoadUnsafe(ref right, i); + result.StoreUnsafe(ref left, i); } } - else if (AdvSimd.IsSupported) + else if (Vector128.IsHardwareAccelerated) { - fixed (int* leftPtr = thisArray) - fixed (int* rightPtr = valueArray) + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) { - for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) - { - Vector128 leftVec = AdvSimd.LoadVector128(leftPtr + i); - Vector128 rightVec = AdvSimd.LoadVector128(rightPtr + i); - AdvSimd.Store(leftPtr + i, AdvSimd.And(leftVec, rightVec)); - } + Vector128 result = Vector128.LoadUnsafe(ref left, i) & Vector128.LoadUnsafe(ref right, i); + result.StoreUnsafe(ref left, i); } } @@ -486,43 +420,24 @@ public unsafe BitArray Or(BitArray value) } uint i = 0; - if (Avx2.IsSupported) - { - fixed (int* leftPtr = thisArray) - fixed (int* rightPtr = valueArray) - { - for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) - { - Vector256 leftVec = Avx.LoadVector256(leftPtr + i); - Vector256 rightVec = Avx.LoadVector256(rightPtr + i); - Avx.Store(leftPtr + i, Avx2.Or(leftVec, rightVec)); - } - } - } - else if (Sse2.IsSupported) + + ref int left = ref MemoryMarshal.GetArrayDataReference(thisArray); + ref int right = ref MemoryMarshal.GetArrayDataReference(valueArray); + + if (Vector256.IsHardwareAccelerated) { - fixed (int* leftPtr = thisArray) - fixed (int* rightPtr = valueArray) + for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) { - for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) - { - Vector128 leftVec = Sse2.LoadVector128(leftPtr + i); - Vector128 rightVec = Sse2.LoadVector128(rightPtr + i); - Sse2.Store(leftPtr + i, Sse2.Or(leftVec, rightVec)); - } + Vector256 result = Vector256.LoadUnsafe(ref left, i) | Vector256.LoadUnsafe(ref right, i); + result.StoreUnsafe(ref left, i); } } - else if (AdvSimd.IsSupported) + else if (Vector128.IsHardwareAccelerated) { - fixed (int* leftPtr = thisArray) - fixed (int* rightPtr = valueArray) + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) { - for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) - { - Vector128 leftVec = AdvSimd.LoadVector128(leftPtr + i); - Vector128 rightVec = AdvSimd.LoadVector128(rightPtr + i); - AdvSimd.Store(leftPtr + i, AdvSimd.Or(leftVec, rightVec)); - } + Vector128 result = Vector128.LoadUnsafe(ref left, i) | Vector128.LoadUnsafe(ref right, i); + result.StoreUnsafe(ref left, i); } } @@ -572,43 +487,24 @@ public unsafe BitArray Xor(BitArray value) } uint i = 0; - if (Avx2.IsSupported) + + ref int left = ref MemoryMarshal.GetArrayDataReference(thisArray); + ref int right = ref MemoryMarshal.GetArrayDataReference(valueArray); + + if (Vector256.IsHardwareAccelerated) { - fixed (int* leftPtr = m_array) - fixed (int* rightPtr = value.m_array) + for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) { - for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) - { - Vector256 leftVec = Avx.LoadVector256(leftPtr + i); - Vector256 rightVec = Avx.LoadVector256(rightPtr + i); - Avx.Store(leftPtr + i, Avx2.Xor(leftVec, rightVec)); - } + Vector256 result = Vector256.LoadUnsafe(ref left, i) ^ Vector256.LoadUnsafe(ref right, i); + result.StoreUnsafe(ref left, i); } } - else if (Sse2.IsSupported) + else if (Vector128.IsHardwareAccelerated) { - fixed (int* leftPtr = thisArray) - fixed (int* rightPtr = valueArray) + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) { - for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) - { - Vector128 leftVec = Sse2.LoadVector128(leftPtr + i); - Vector128 rightVec = Sse2.LoadVector128(rightPtr + i); - Sse2.Store(leftPtr + i, Sse2.Xor(leftVec, rightVec)); - } - } - } - else if (AdvSimd.IsSupported) - { - fixed (int* leftPtr = thisArray) - fixed (int* rightPtr = valueArray) - { - for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) - { - Vector128 leftVec = AdvSimd.LoadVector128(leftPtr + i); - Vector128 rightVec = AdvSimd.LoadVector128(rightPtr + i); - AdvSimd.Store(leftPtr + i, AdvSimd.Xor(leftVec, rightVec)); - } + Vector128 result = Vector128.LoadUnsafe(ref left, i) ^ Vector128.LoadUnsafe(ref right, i); + result.StoreUnsafe(ref left, i); } } @@ -650,39 +546,23 @@ public unsafe BitArray Not() } uint i = 0; - if (Avx2.IsSupported) - { - Vector256 ones = Vector256.Create(-1); - fixed (int* ptr = thisArray) - { - for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) - { - Vector256 vec = Avx.LoadVector256(ptr + i); - Avx.Store(ptr + i, Avx2.Xor(vec, ones)); - } - } - } - else if (Sse2.IsSupported) + + ref int value = ref MemoryMarshal.GetArrayDataReference(thisArray); + + if (Vector256.IsHardwareAccelerated) { - Vector128 ones = Vector128.Create(-1); - fixed (int* ptr = thisArray) + for (; i < (uint)count - (Vector256IntCount - 1u); i += Vector256IntCount) { - for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) - { - Vector128 vec = Sse2.LoadVector128(ptr + i); - Sse2.Store(ptr + i, Sse2.Xor(vec, ones)); - } + Vector256 result = ~Vector256.LoadUnsafe(ref value, i); + result.StoreUnsafe(ref value, i); } } - else if (AdvSimd.IsSupported) + else if (Vector128.IsHardwareAccelerated) { - fixed (int* leftPtr = thisArray) + for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) { - for (; i < (uint)count - (Vector128IntCount - 1u); i += Vector128IntCount) - { - Vector128 leftVec = AdvSimd.LoadVector128(leftPtr + i); - AdvSimd.Store(leftPtr + i, AdvSimd.Not(leftVec)); - } + Vector128 result = ~Vector128.LoadUnsafe(ref value, i); + result.StoreUnsafe(ref value, i); } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/NuGet.config b/src/libraries/System.Configuration.ConfigurationManager/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Configuration.ConfigurationManager/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Console/src/Resources/Strings.resx b/src/libraries/System.Console/src/Resources/Strings.resx index 9e0151c9df0feb..ce8a2ad62fc9ec 100644 --- a/src/libraries/System.Console/src/Resources/Strings.resx +++ b/src/libraries/System.Console/src/Resources/Strings.resx @@ -254,4 +254,7 @@ The terminfo database has an invalid magic number: '{0}'. + + System.Console is not supported on this platform. + diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index 3655d81f0730e9..4088dda76c070d 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -1,10 +1,15 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) enable - + + + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) + SR.PlatformNotSupported_SystemConsole + + diff --git a/src/libraries/System.Data.Common/System.Data.Common.sln b/src/libraries/System.Data.Common/System.Data.Common.sln index c00d69d2f0910b..052a1af043cc4d 100644 --- a/src/libraries/System.Data.Common/System.Data.Common.sln +++ b/src/libraries/System.Data.Common/System.Data.Common.sln @@ -15,7 +15,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Data.Common", "src\S EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Data.Common.Tests", "tests\System.Data.Common.Tests.csproj", "{BEBD7B5B-9544-42EB-B878-F009560CAAF4}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{D5A85F0E-509A-424F-BFD0-A7CC38D43CCD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{D5A85F0E-509A-424F-BFD0-A7CC38D43CCD}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Uri", "..\System.Private.Uri\src\System.Private.Uri.csproj", "{7AB121D2-0AAC-48E0-A834-6E220ECFEC4D}" EndProject diff --git a/src/libraries/System.Data.Odbc/NuGet.config b/src/libraries/System.Data.Odbc/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Data.Odbc/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Data.OleDb/NuGet.config b/src/libraries/System.Data.OleDb/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Data.OleDb/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj index 62b3ffd01287c6..7e3cf5c3a8f8f6 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0-windows;netstandard2.0;$(NetFrameworkMinimum) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true enable @@ -129,13 +129,10 @@ System.Data.OleDb.OleDbTransaction - + - - - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterCategoryTests.cs b/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterCategoryTests.cs index b7da86114a334d..6ab827529886ed 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterCategoryTests.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterCategoryTests.cs @@ -78,7 +78,7 @@ public static void PerformanceCounterCategory_GetCounterHelp_Invalid() } [ConditionalFact(typeof(Helpers), nameof(Helpers.IsElevatedAndCanWriteAndReadNetPerfCounters))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows), nameof(PlatformDetection.Is64BitProcess))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows))] public static void PerformanceCounterCategory_CategoryType_MultiInstance() { string categoryName = nameof(PerformanceCounterCategory_CategoryType_MultiInstance) + "_Category"; @@ -267,7 +267,7 @@ public static void PerformanceCounterCategory_InstanceExists_Invalid() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows), nameof(PlatformDetection.Is64BitProcess))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows))] public static void PerformanceCounterCategory_InstanceExists_Static() { PerformanceCounterCategory pcc = Helpers.RetryOnAllPlatforms(() => new PerformanceCounterCategory("Processor")); @@ -291,7 +291,7 @@ public static void PerformanceCounterCategory_InstanceExists_StaticInvalid() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows), nameof(PlatformDetection.Is64BitProcess))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows))] public static void PerformanceCounterCategory_ReadCategory() { PerformanceCounterCategory pcc = Helpers.RetryOnAllPlatforms(() => new PerformanceCounterCategory("Processor")); diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterTests.cs b/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterTests.cs index 89770aa2321fd1..94c7cb51886015 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterTests.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/tests/PerformanceCounterTests.cs @@ -39,7 +39,7 @@ public static void PerformanceCounter_CreateCounter_Count0() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows), nameof(PlatformDetection.Is64BitProcess))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows))] public static void PerformanceCounter_CreateCounter_ProcessorCounter() { using (PerformanceCounter counterSample = new PerformanceCounter("Processor", "Interrupts/sec", "0", ".")) @@ -188,7 +188,7 @@ public static void PerformanceCounter_BeginInit_ProcessorCounter() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows), nameof(PlatformDetection.Is64BitProcess))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows))] public static void PerformanceCounter_BeginInitEndInit_ProcessorCounter() { using (PerformanceCounter counterSample = new PerformanceCounter("Processor", "Interrupts/sec", "0", ".")) @@ -270,7 +270,7 @@ public static void PerformanceCounter_Increment_IncrementReadOnly() } [ConditionalFact(typeof(Helpers), nameof(Helpers.IsElevatedAndCanWriteAndReadNetPerfCounters))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows), nameof(PlatformDetection.Is64BitProcess))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/60933", typeof(PlatformDetection), nameof(PlatformDetection.IsWindows))] public static void PerformanceCounter_Decrement_DecrementReadOnly() { string categoryName = nameof(PerformanceCounter_Decrement_DecrementReadOnly) + "_Category"; diff --git a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj index 2279a7ca2325ed..2521808c43c2da 100644 --- a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj +++ b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj @@ -353,8 +353,8 @@ - + diff --git a/src/libraries/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.sln b/src/libraries/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.sln index 3a94f61372172d..6eec7119d583f4 100644 --- a/src/libraries/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.sln +++ b/src/libraries/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.sln @@ -21,7 +21,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.StackTra EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.Tracing", "..\System.Diagnostics.Tracing\src\System.Diagnostics.Tracing.csproj", "{96501106-36D0-4093-8FEE-AF90713D09ED}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{0269FFAF-E680-4BC8-A1B4-0333D77911BC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{0269FFAF-E680-4BC8-A1B4-0333D77911BC}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Uri", "..\System.Private.Uri\src\System.Private.Uri.csproj", "{E6DD9860-2824-43D3-BD9D-87ED396B4E46}" EndProject diff --git a/src/libraries/System.Diagnostics.Tools/System.Diagnostics.Tools.sln b/src/libraries/System.Diagnostics.Tools/System.Diagnostics.Tools.sln index 0b36efa0d9686a..f3b1e4c2920638 100644 --- a/src/libraries/System.Diagnostics.Tools/System.Diagnostics.Tools.sln +++ b/src/libraries/System.Diagnostics.Tools/System.Diagnostics.Tools.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.Tools", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.Tools.Tests", "tests\System.Diagnostics.Tools.Tests.csproj", "{A63F3AEA-F4ED-4047-A11F-490325530D92}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{103898BF-8D8F-4A35-A943-027A47E4BD36}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{103898BF-8D8F-4A35-A943-027A47E4BD36}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{740703FE-F5E0-4BE0-93B2-63ADD4A3EB70}" EndProject diff --git a/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.sln b/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.sln index 8555e36ed6fce4..bca99beaf5d398 100644 --- a/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.sln +++ b/src/libraries/System.Diagnostics.TraceSource/System.Diagnostics.TraceSource.sln @@ -17,7 +17,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.TraceSou EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.TraceSource.Tests", "tests\System.Diagnostics.TraceSource.Tests.csproj", "{0C126AE9-C858-4AC8-9DB1-B8E228BD2DB0}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{8EAD8906-AF4E-42CA-983E-28CFE2224AEE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{8EAD8906-AF4E-42CA-983E-28CFE2224AEE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Uri", "..\System.Private.Uri\src\System.Private.Uri.csproj", "{4DAA5CFC-C59D-4C1B-A12A-BC9863F38C0C}" EndProject diff --git a/src/libraries/System.Diagnostics.Tracing/System.Diagnostics.Tracing.sln b/src/libraries/System.Diagnostics.Tracing/System.Diagnostics.Tracing.sln index f1d89b93b68f66..d35d0997183759 100644 --- a/src/libraries/System.Diagnostics.Tracing/System.Diagnostics.Tracing.sln +++ b/src/libraries/System.Diagnostics.Tracing/System.Diagnostics.Tracing.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.Tracing" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Diagnostics.Tracing.Tests", "tests\System.Diagnostics.Tracing.Tests.csproj", "{24605C4D-2465-433D-A393-45CB950E0834}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{3969DA9E-6C7D-421D-ABCC-BD02DFA36DA4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{3969DA9E-6C7D-421D-ABCC-BD02DFA36DA4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{ADB5AA13-96F9-4A6C-B152-A8295554815E}" EndProject diff --git a/src/libraries/System.DirectoryServices.AccountManagement/NuGet.config b/src/libraries/System.DirectoryServices.AccountManagement/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.DirectoryServices.AccountManagement/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj index ff38f3d644c709..c747c1d187c19b 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj @@ -217,6 +217,9 @@ + + + diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj index 915b7d71b0a9df..0a92754626c1fc 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj @@ -113,6 +113,9 @@ + + + diff --git a/src/libraries/System.Globalization.Calendars/System.Globalization.Calendars.sln b/src/libraries/System.Globalization.Calendars/System.Globalization.Calendars.sln index deb978b098d275..2f08e763ec629f 100644 --- a/src/libraries/System.Globalization.Calendars/System.Globalization.Calendars.sln +++ b/src/libraries/System.Globalization.Calendars/System.Globalization.Calendars.sln @@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.Calend EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.Calendars.Tests", "tests\System.Globalization.Calendars.Tests.csproj", "{BFEF5B19-7D03-42BA-9CD1-D1B53F35D706}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{617B4727-AA14-4840-8898-1947D7C6E437}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{617B4727-AA14-4840-8898-1947D7C6E437}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{7AE40769-89B3-4881-96F4-0EC78CD5610E}" EndProject diff --git a/src/libraries/System.Globalization/System.Globalization.sln b/src/libraries/System.Globalization/System.Globalization.sln index 5f7f51bb8fb10f..3c692ba63029a1 100644 --- a/src/libraries/System.Globalization/System.Globalization.sln +++ b/src/libraries/System.Globalization/System.Globalization.sln @@ -15,7 +15,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.Nls.Te EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.Tests", "tests\System.Globalization.Tests.csproj", "{A66D589C-6FEE-41EE-A7D9-C5306BF5AE47}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{74CAB3C9-1AE1-467E-B139-35E7113F4660}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{74CAB3C9-1AE1-467E-B139-35E7113F4660}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{BF058293-0E5D-412C-A0B0-E55AF943278E}" EndProject diff --git a/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj b/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj index 1e825eda0cb98e..c34b54ed173f93 100644 --- a/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj +++ b/src/libraries/System.IO.Compression.ZipFile/src/System.IO.Compression.ZipFile.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) enable diff --git a/src/libraries/System.IO.Compression/ref/System.IO.Compression.cs b/src/libraries/System.IO.Compression/ref/System.IO.Compression.cs index 80b7286baa5416..3090d4aaba384c 100644 --- a/src/libraries/System.IO.Compression/ref/System.IO.Compression.cs +++ b/src/libraries/System.IO.Compression/ref/System.IO.Compression.cs @@ -94,6 +94,8 @@ public ZipArchive(System.IO.Stream stream) { } public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode) { } public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen) { } public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen, System.Text.Encoding? entryNameEncoding) { } + [System.Diagnostics.CodeAnalysis.AllowNull] + public string Comment { get { throw null; } set { } } public System.Collections.ObjectModel.ReadOnlyCollection Entries { get { throw null; } } public System.IO.Compression.ZipArchiveMode Mode { get { throw null; } } public System.IO.Compression.ZipArchiveEntry CreateEntry(string entryName) { throw null; } @@ -106,6 +108,8 @@ public partial class ZipArchiveEntry { internal ZipArchiveEntry() { } public System.IO.Compression.ZipArchive Archive { get { throw null; } } + [System.Diagnostics.CodeAnalysis.AllowNull] + public string Comment { get { throw null; } set { } } public long CompressedLength { get { throw null; } } [System.CLSCompliantAttribute(false)] public uint Crc32 { get { throw null; } } diff --git a/src/libraries/System.IO.Compression/src/Resources/Strings.resx b/src/libraries/System.IO.Compression/src/Resources/Strings.resx index 08e13fd1bb1445..1f209ff17f42bc 100644 --- a/src/libraries/System.IO.Compression/src/Resources/Strings.resx +++ b/src/libraries/System.IO.Compression/src/Resources/Strings.resx @@ -212,8 +212,8 @@ Cannot access entries in Create mode. - - The specified entry name encoding is not supported. + + The specified encoding is not supported for entry names and comments. Entry names cannot require more than 2^16 bits. @@ -302,4 +302,7 @@ An entry named '{0}' already exists in the archive. + + System.IO.Compression is not supported on this platform. + diff --git a/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj b/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj index be3f42bcd86f5e..8a33c737f13e66 100644 --- a/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj +++ b/src/libraries/System.IO.Compression/src/System.IO.Compression.csproj @@ -1,10 +1,15 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) enable - + + + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) + SR.PlatformNotSupported_Compression + + diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs index 58b65209caf0eb..5d68416b3b25da 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchive.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text; namespace System.IO.Compression @@ -27,8 +28,8 @@ public class ZipArchive : IDisposable private uint _numberOfThisDisk; //only valid after ReadCentralDirectory private long _expectedNumberOfEntries; private Stream? _backingStream; - private byte[]? _archiveComment; - private Encoding? _entryNameEncoding; + private byte[] _archiveComment; + private Encoding? _entryNameAndCommentEncoding; #if DEBUG_FORCE_ZIP64 public bool _forceZip64; @@ -121,7 +122,7 @@ public ZipArchive(Stream stream, ZipArchiveMode mode, bool leaveOpen, Encoding? if (stream == null) throw new ArgumentNullException(nameof(stream)); - EntryNameEncoding = entryNameEncoding; + EntryNameAndCommentEncoding = entryNameEncoding; Stream? extraTempStream = null; try @@ -173,7 +174,7 @@ public ZipArchive(Stream stream, ZipArchiveMode mode, bool leaveOpen, Encoding? _centralDirectoryStart = 0; // invalid until ReadCentralDirectory _isDisposed = false; _numberOfThisDisk = 0; // invalid until ReadCentralDirectory - _archiveComment = null; + _archiveComment = Array.Empty(); switch (mode) { @@ -211,6 +212,20 @@ public ZipArchive(Stream stream, ZipArchiveMode mode, bool leaveOpen, Encoding? } } + /// + /// Gets or sets the optional archive comment. + /// + /// + /// The comment encoding is determined by the entryNameEncoding parameter of the constructor. + /// If the comment byte length is larger than , it will be truncated when disposing the archive. + /// + [AllowNull] + public string Comment + { + get => (EntryNameAndCommentEncoding ?? Encoding.UTF8).GetString(_archiveComment); + set => _archiveComment = ZipHelper.GetEncodedTruncatedBytesFromString(value, EntryNameAndCommentEncoding, ZipEndOfCentralDirectoryBlock.ZipFileCommentMaxLength, out _); + } + /// /// The collection of entries that are currently in the ZipArchive. This may not accurately represent the actual entries that are present in the underlying file or stream. /// @@ -345,9 +360,9 @@ public void Dispose() internal uint NumberOfThisDisk => _numberOfThisDisk; - internal Encoding? EntryNameEncoding + internal Encoding? EntryNameAndCommentEncoding { - get { return _entryNameEncoding; } + get => _entryNameAndCommentEncoding; private set { @@ -370,10 +385,10 @@ private set (value.Equals(Encoding.BigEndianUnicode) || value.Equals(Encoding.Unicode))) { - throw new ArgumentException(SR.EntryNameEncodingNotSupported, nameof(EntryNameEncoding)); + throw new ArgumentException(SR.EntryNameAndCommentEncodingNotSupported, nameof(EntryNameAndCommentEncoding)); } - _entryNameEncoding = value; + _entryNameAndCommentEncoding = value; } } @@ -547,9 +562,7 @@ private void ReadEndOfCentralDirectory() _expectedNumberOfEntries = eocd.NumberOfEntriesInTheCentralDirectory; - // only bother saving the comment if we are in update mode - if (_mode == ZipArchiveMode.Update) - _archiveComment = eocd.ArchiveComment; + _archiveComment = eocd.ArchiveComment; TryReadZip64EndOfCentralDirectory(eocd, eocdStart); diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs index 0d5de3cbac6bd2..f16c193383ae8a 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs @@ -40,10 +40,11 @@ public partial class ZipArchiveEntry // only apply to update mode private List? _cdUnknownExtraFields; private List? _lhUnknownExtraFields; - private readonly byte[]? _fileComment; + private byte[] _fileComment; private readonly CompressionLevel? _compressionLevel; + private bool _hasUnicodeEntryNameOrComment; - // Initializes, attaches it to archive + // Initializes a ZipArchiveEntry instance for an existing archive entry. internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd) { _archive = archive; @@ -72,17 +73,22 @@ internal ZipArchiveEntry(ZipArchive archive, ZipCentralDirectoryFileHeader cd) _everOpenedForWrite = false; _outstandingWriteStream = null; - FullName = DecodeEntryName(cd.Filename); + _storedEntryNameBytes = cd.Filename; + _storedEntryName = (_archive.EntryNameAndCommentEncoding ?? Encoding.UTF8).GetString(_storedEntryNameBytes); + DetectEntryNameVersion(); _lhUnknownExtraFields = null; - // the cd should have these as null if we aren't in Update mode + // the cd should have this as null if we aren't in Update mode _cdUnknownExtraFields = cd.ExtraFields; + _fileComment = cd.FileComment; _compressionLevel = null; + + _hasUnicodeEntryNameOrComment = (_generalPurposeBitFlag & BitFlagValues.UnicodeFileNameAndComment) != 0; } - // Initializes new entry + // Initializes a ZipArchiveEntry instance for a new archive entry with a specified compression level. internal ZipArchiveEntry(ZipArchive archive, string entryName, CompressionLevel compressionLevel) : this(archive, entryName) { @@ -93,7 +99,7 @@ internal ZipArchiveEntry(ZipArchive archive, string entryName, CompressionLevel } } - // Initializes new entry + // Initializes a ZipArchiveEntry instance for a new archive entry. internal ZipArchiveEntry(ZipArchive archive, string entryName) { _archive = archive; @@ -125,7 +131,8 @@ internal ZipArchiveEntry(ZipArchive archive, string entryName) _cdUnknownExtraFields = null; _lhUnknownExtraFields = null; - _fileComment = null; + + _fileComment = Array.Empty(); _compressionLevel = null; @@ -137,6 +144,8 @@ internal ZipArchiveEntry(ZipArchive archive, string entryName) { _archive.AcquireArchiveStream(this); } + + _hasUnicodeEntryNameOrComment = false; } /// @@ -174,6 +183,24 @@ public int ExternalAttributes } } + /// + /// Gets or sets the optional entry comment. + /// + /// + ///The comment encoding is determined by the entryNameEncoding parameter of the constructor. + /// If the comment byte length is larger than , it will be truncated when disposing the archive. + /// + [AllowNull] + public string Comment + { + get => (_archive.EntryNameAndCommentEncoding ?? Encoding.UTF8).GetString(_fileComment); + set + { + _fileComment = ZipHelper.GetEncodedTruncatedBytesFromString(value, _archive.EntryNameAndCommentEncoding, ushort.MaxValue, out bool isUTF8); + _hasUnicodeEntryNameOrComment |= isUTF8; + } + } + /// /// The relative path of the entry as stored in the Zip archive. Note that Zip archives allow any string to be the path of the entry, including invalid and absolute paths. /// @@ -191,17 +218,13 @@ private set if (value == null) throw new ArgumentNullException(nameof(FullName)); - bool isUTF8; - _storedEntryNameBytes = EncodeEntryName(value, out isUTF8); - _storedEntryName = value; + _storedEntryNameBytes = ZipHelper.GetEncodedTruncatedBytesFromString( + value, _archive.EntryNameAndCommentEncoding, 0 /* No truncation */, out bool hasUnicodeEntryName); - if (isUTF8) - _generalPurposeBitFlag |= BitFlagValues.UnicodeFileName; - else - _generalPurposeBitFlag &= ~BitFlagValues.UnicodeFileName; + _hasUnicodeEntryNameOrComment |= hasUnicodeEntryName; + _storedEntryName = value; - if (ParseFileName(value, _versionMadeByPlatform) == "") - VersionToExtractAtLeast(ZipVersionNeededValues.ExplicitDirectory); + DetectEntryNameVersion(); } } @@ -396,39 +419,6 @@ private CompressionMethodValues CompressionMethod } } - private string DecodeEntryName(byte[] entryNameBytes) - { - Debug.Assert(entryNameBytes != null); - - Encoding readEntryNameEncoding; - if ((_generalPurposeBitFlag & BitFlagValues.UnicodeFileName) == 0) - { - readEntryNameEncoding = _archive == null ? - Encoding.UTF8 : - _archive.EntryNameEncoding ?? Encoding.UTF8; - } - else - { - readEntryNameEncoding = Encoding.UTF8; - } - - return readEntryNameEncoding.GetString(entryNameBytes); - } - - private byte[] EncodeEntryName(string entryName, out bool isUTF8) - { - Debug.Assert(entryName != null); - - Encoding writeEntryNameEncoding; - if (_archive != null && _archive.EntryNameEncoding != null) - writeEntryNameEncoding = _archive.EntryNameEncoding; - else - writeEntryNameEncoding = ZipHelper.RequiresUnicode(entryName) ? Encoding.UTF8 : Encoding.ASCII; - - isUTF8 = writeEntryNameEncoding.Equals(Encoding.UTF8); - return writeEntryNameEncoding.GetBytes(entryName); - } - // does almost everything you need to do to forget about this entry // writes the local header/data, gets rid of all the data, // closes all of the streams except for the very outermost one that @@ -516,6 +506,11 @@ internal void WriteCentralDirectoryFileHeader() extraFieldLength = (ushort)bigExtraFieldLength; } + if (_hasUnicodeEntryNameOrComment) + _generalPurposeBitFlag |= BitFlagValues.UnicodeFileNameAndComment; + else + _generalPurposeBitFlag &= ~BitFlagValues.UnicodeFileNameAndComment; + writer.Write(ZipCentralDirectoryFileHeader.SignatureConstant); // Central directory file header signature (4 bytes) writer.Write((byte)_versionMadeBySpecification); // Version made by Specification (version) (1 byte) writer.Write((byte)CurrentZipPlatform); // Version made by Compatibility (type) (1 byte) @@ -529,10 +524,9 @@ internal void WriteCentralDirectoryFileHeader() writer.Write((ushort)_storedEntryNameBytes.Length); // File Name Length (2 bytes) writer.Write(extraFieldLength); // Extra Field Length (2 bytes) - // This should hold because of how we read it originally in ZipCentralDirectoryFileHeader: - Debug.Assert((_fileComment == null) || (_fileComment.Length <= ushort.MaxValue)); + Debug.Assert(_fileComment.Length <= ushort.MaxValue); - writer.Write(_fileComment != null ? (ushort)_fileComment.Length : (ushort)0); // file comment length + writer.Write((ushort)_fileComment.Length); writer.Write((ushort)0); // disk number start writer.Write((ushort)0); // internal file attributes writer.Write(_externalFileAttr); // external file attributes @@ -546,7 +540,7 @@ internal void WriteCentralDirectoryFileHeader() if (_cdUnknownExtraFields != null) ZipGenericExtraField.WriteAllBlocks(_cdUnknownExtraFields, _archive.ArchiveStream); - if (_fileComment != null) + if (_fileComment.Length > 0) writer.Write(_fileComment); } @@ -596,6 +590,14 @@ internal void ThrowIfNotOpenable(bool needToUncompress, bool needToLoadIntoMemor throw new InvalidDataException(message); } + private void DetectEntryNameVersion() + { + if (ParseFileName(_storedEntryName, _versionMadeByPlatform) == "") + { + VersionToExtractAtLeast(ZipVersionNeededValues.ExplicitDirectory); + } + } + private CheckSumAndSizeWriteStream GetDataCompressor(Stream backingStream, bool leaveBackingStreamOpen, EventHandler? onClose) { // stream stack: backingStream -> DeflateStream -> CheckSumWriteStream @@ -1303,7 +1305,7 @@ protected override void Dispose(bool disposing) } [Flags] - internal enum BitFlagValues : ushort { DataDescriptor = 0x8, UnicodeFileName = 0x800 } + internal enum BitFlagValues : ushort { DataDescriptor = 0x8, UnicodeFileNameAndComment = 0x800 } internal enum CompressionMethodValues : ushort { Stored = 0x0, Deflate = 0x8, Deflate64 = 0x9, BZip2 = 0xC, LZMA = 0xE } } diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs index 058a8617dea61c..64fffd2e1f945d 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs @@ -453,7 +453,7 @@ internal struct ZipCentralDirectoryFileHeader public long RelativeOffsetOfLocalHeader; public byte[] Filename; - public byte[]? FileComment; + public byte[] FileComment; public List? ExtraFields; // if saveExtraFieldsAndComments is false, FileComment and ExtraFields will be null @@ -513,13 +513,7 @@ public static bool TryReadBlock(BinaryReader reader, bool saveExtraFieldsAndComm // of the ExtraField block. Thus we must force the stream's position to the proper place. reader.BaseStream.AdvanceToPosition(endExtraFields); - if (saveExtraFieldsAndComments) - header.FileComment = reader.ReadBytes(header.FileCommentLength); - else - { - reader.BaseStream.Position += header.FileCommentLength; - header.FileComment = null; - } + header.FileComment = reader.ReadBytes(header.FileCommentLength); header.UncompressedSize = zip64.UncompressedSize == null ? uncompressedSizeSmall diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.cs index 57ff0eafd993b6..1e46185461a294 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.cs @@ -1,7 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Text; namespace System.IO.Compression { @@ -17,20 +20,19 @@ internal static class ZipHelper private static readonly DateTime s_invalidDateIndicator = new DateTime(ValidZipDate_YearMin, 1, 1, 0, 0, 0); - internal static bool RequiresUnicode(string test) + internal static Encoding GetEncoding(string text) { - Debug.Assert(test != null); - - foreach (char c in test) + foreach (char c in text) { // The Zip Format uses code page 437 when the Unicode bit is not set. This format // is the same as ASCII for characters 32-126 but differs otherwise. If we can fit // the string into CP437 then we treat ASCII as acceptable. if (c > 126 || c < 32) - return true; + { + return Encoding.UTF8; + } } - - return false; + return Encoding.ASCII; } /// @@ -193,5 +195,50 @@ private static bool SeekBackwardsAndRead(Stream stream, byte[] buffer, out int b return true; } } + + // Converts the specified string into bytes using the optional specified encoding. + // If the encoding null, then the encoding is calculated from the string itself. + // If maxBytes is greater than zero, the returned string will be truncated to a total + // number of characters whose bytes do not add up to more than that number. + internal static byte[] GetEncodedTruncatedBytesFromString(string? text, Encoding? encoding, int maxBytes, out bool isUTF8) + { + if (string.IsNullOrEmpty(text)) + { + isUTF8 = false; + return Array.Empty(); + } + + encoding ??= GetEncoding(text); + isUTF8 = encoding.CodePage == 65001; + + if (maxBytes == 0) // No truncation + { + return encoding.GetBytes(text); + } + + byte[] bytes; + if (isUTF8) + { + int totalCodePoints = 0; + foreach (Rune rune in text.EnumerateRunes()) + { + if (totalCodePoints + rune.Utf8SequenceLength > maxBytes) + { + break; + } + totalCodePoints += rune.Utf8SequenceLength; + } + + bytes = encoding.GetBytes(text); + + Debug.Assert(totalCodePoints > 0); + Debug.Assert(totalCodePoints <= bytes.Length); + + return bytes[0..totalCodePoints]; + } + + bytes = encoding.GetBytes(text); + return maxBytes < bytes.Length ? bytes[0..maxBytes] : bytes; + } } } diff --git a/src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj b/src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj index 509c7202afb435..adac7a348c6922 100644 --- a/src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj +++ b/src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj @@ -20,11 +20,13 @@ + + diff --git a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_CreateTests.Comments.cs b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_CreateTests.Comments.cs new file mode 100644 index 00000000000000..d04ab6c6d1d590 --- /dev/null +++ b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_CreateTests.Comments.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; +using System.Text; + +namespace System.IO.Compression.Tests +{ + public partial class zip_CreateTests : ZipFileTestBase + { + [Theory] + [MemberData(nameof(Utf8Comment_Data))] + public static void Create_Comment_AsciiEntryName_NullEncoding(string originalComment, string expectedComment) => + Create_Comment_EntryName_Encoding_Internal(AsciiFileName, originalComment, expectedComment, null); + + [Theory] + [MemberData(nameof(Utf8Comment_Data))] + public static void Create_Comment_AsciiEntryName_Utf8Encoding(string originalComment, string expectedComment) => + Create_Comment_EntryName_Encoding_Internal(AsciiFileName, originalComment, expectedComment, Encoding.UTF8); + + [Theory] + [MemberData(nameof(Latin1Comment_Data))] + public static void Create_Comment_AsciiEntryName_Latin1Encoding(string originalComment, string expectedComment) => + Create_Comment_EntryName_Encoding_Internal(AsciiFileName, originalComment, expectedComment, Encoding.Latin1); + + [Theory] + [MemberData(nameof(Utf8Comment_Data))] + public static void Create_Comment_Utf8EntryName_NullEncoding(string originalComment, string expectedComment) => + Create_Comment_EntryName_Encoding_Internal(Utf8FileName, originalComment, expectedComment, null); + + [Theory] + [MemberData(nameof(Utf8Comment_Data))] + public static void Create_Comment_Utf8EntryName_Utf8Encoding(string originalComment, string expectedComment) => + Create_Comment_EntryName_Encoding_Internal(Utf8FileName, originalComment, expectedComment, Encoding.UTF8); + + [Theory] + [MemberData(nameof(Latin1Comment_Data))] + public static void Create_Comment_Utf8EntryName_Latin1Encoding(string originalComment, string expectedComment) => + // Emoji not supported by latin1 + Create_Comment_EntryName_Encoding_Internal(Utf8AndLatin1FileName, originalComment, expectedComment, Encoding.Latin1); + + private static void Create_Comment_EntryName_Encoding_Internal(string entryName, string originalComment, string expectedComment, Encoding encoding) + { + using var ms = new MemoryStream(); + + using (var zip = new ZipArchive(ms, ZipArchiveMode.Create, leaveOpen: true, encoding)) + { + ZipArchiveEntry entry = zip.CreateEntry(entryName, CompressionLevel.NoCompression); + entry.Comment = originalComment; + Assert.Equal(expectedComment, entry.Comment); + } + + using (var zip = new ZipArchive(ms, ZipArchiveMode.Read, leaveOpen: false, encoding)) + { + foreach (ZipArchiveEntry entry in zip.Entries) + { + Assert.Equal(entryName, entry.Name); + Assert.Equal(expectedComment, entry.Comment); + } + } + } + } +} \ No newline at end of file diff --git a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_CreateTests.cs b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_CreateTests.cs index f0c36d5967626b..a964f5da7587f1 100644 --- a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_CreateTests.cs +++ b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_CreateTests.cs @@ -1,14 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; using System.Threading.Tasks; using Xunit; -using Microsoft.DotNet.XUnitExtensions; namespace System.IO.Compression.Tests { - public class zip_CreateTests : ZipFileTestBase + public partial class zip_CreateTests : ZipFileTestBase { [Fact] public static void CreateModeInvalidOperations() diff --git a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_UpdateTests.Comments.cs b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_UpdateTests.Comments.cs new file mode 100644 index 00000000000000..7195dd504e0755 --- /dev/null +++ b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_UpdateTests.Comments.cs @@ -0,0 +1,95 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace System.IO.Compression.Tests +{ + public partial class zip_UpdateTests : ZipFileTestBase + { + [Theory] + [MemberData(nameof(Utf8Comment_Data))] + public static void Update_Comment_AsciiEntryName_NullEncoding(string originalComment, string expectedComment) => + Update_Comment_EntryName_Encoding_Internal(AsciiFileName, + originalComment, expectedComment, null, + ALettersUShortMaxValueMinusOneAndCopyRightChar, ALettersUShortMaxValueMinusOne); + + [Theory] + [MemberData(nameof(Utf8Comment_Data))] + public static void Update_Comment_AsciiEntryName_Utf8Encoding(string originalComment, string expectedComment) => + Update_Comment_EntryName_Encoding_Internal(AsciiFileName, + originalComment, expectedComment, Encoding.UTF8, + ALettersUShortMaxValueMinusOneAndCopyRightChar, ALettersUShortMaxValueMinusOne); + + [Theory] + [MemberData(nameof(Latin1Comment_Data))] + public static void Update_Comment_AsciiEntryName_Latin1Encoding(string originalComment, string expectedComment) => + Update_Comment_EntryName_Encoding_Internal(AsciiFileName, + originalComment, expectedComment, Encoding.Latin1, + ALettersUShortMaxValueMinusOneAndTwoCopyRightChars, ALettersUShortMaxValueMinusOneAndCopyRightChar); + + [Theory] + [MemberData(nameof(Utf8Comment_Data))] + public static void Update_Comment_Utf8EntryName_NullEncoding(string originalComment, string expectedComment) => + Update_Comment_EntryName_Encoding_Internal(Utf8FileName, + originalComment, expectedComment, null, + ALettersUShortMaxValueMinusOneAndCopyRightChar, ALettersUShortMaxValueMinusOne); + + [Theory] + [MemberData(nameof(Utf8Comment_Data))] + public static void Update_Comment_Utf8EntryName_Utf8Encoding(string originalComment, string expectedComment) => + Update_Comment_EntryName_Encoding_Internal(Utf8FileName, + originalComment, expectedComment, Encoding.UTF8, + ALettersUShortMaxValueMinusOneAndCopyRightChar, ALettersUShortMaxValueMinusOne); + + [Theory] + [MemberData(nameof(Latin1Comment_Data))] + public static void Update_Comment_Utf8EntryName_Latin1Encoding(string originalComment, string expectedComment) => + // Emoji is not supported/detected in latin1 + Update_Comment_EntryName_Encoding_Internal(Utf8AndLatin1FileName, + originalComment, expectedComment, Encoding.Latin1, + ALettersUShortMaxValueMinusOneAndTwoCopyRightChars, ALettersUShortMaxValueMinusOneAndCopyRightChar); + + private static void Update_Comment_EntryName_Encoding_Internal(string entryName, + string originalCreateComment, string expectedCreateComment, Encoding encoding, + string originalUpdateComment, string expectedUpdateComment) + { + using var ms = new MemoryStream(); + + using (var zip = new ZipArchive(ms, ZipArchiveMode.Create, leaveOpen: true, encoding)) + { + ZipArchiveEntry entry = zip.CreateEntry(entryName, CompressionLevel.NoCompression); + entry.Comment = originalCreateComment; + Assert.Equal(expectedCreateComment, entry.Comment); + } + + using (var zip = new ZipArchive(ms, ZipArchiveMode.Read, leaveOpen: true, encoding)) + { + foreach (ZipArchiveEntry entry in zip.Entries) + { + Assert.Equal(expectedCreateComment, entry.Comment); + } + } + + using (var zip = new ZipArchive(ms, ZipArchiveMode.Update, leaveOpen: true, encoding)) + { + foreach (ZipArchiveEntry entry in zip.Entries) + { + entry.Comment = originalUpdateComment; + Assert.Equal(expectedUpdateComment, entry.Comment); + } + } + + using (var zip = new ZipArchive(ms, ZipArchiveMode.Read, leaveOpen: false, encoding)) + { + foreach (ZipArchiveEntry entry in zip.Entries) + { + Assert.Equal(expectedUpdateComment, entry.Comment); + } + } + } + } +} \ No newline at end of file diff --git a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_UpdateTests.cs b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_UpdateTests.cs index 3cb9934fb3a7ca..637d04500d77a8 100644 --- a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_UpdateTests.cs +++ b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_UpdateTests.cs @@ -1,14 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.InteropServices; +using System.Collections.Generic; +using System.Linq; using System.Text; using System.Threading.Tasks; using Xunit; namespace System.IO.Compression.Tests { - public class zip_UpdateTests : ZipFileTestBase + public partial class zip_UpdateTests : ZipFileTestBase { [Theory] [InlineData("normal.zip", "normal")] diff --git a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj index 34200ee648be6a..1277500ba61589 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj +++ b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj @@ -86,8 +86,6 @@ Link="Common\System\IO\FileSystem.DirectoryCreation.Windows.cs" /> - - @@ -100,6 +98,8 @@ + + diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj b/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj index f9f7f0dfcfb6bd..2ae15035b5d309 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj +++ b/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent) enable @@ -13,7 +13,11 @@ - + + + + + - + @@ -65,10 +69,6 @@ - - - - diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.Browser.cs b/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.Default.cs similarity index 100% rename from src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.Browser.cs rename to src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.Default.cs diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs b/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrDefault.cs similarity index 100% rename from src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrBrowser.cs rename to src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.UnixOrDefault.cs diff --git a/src/libraries/System.IO.FileSystem/NuGet.config b/src/libraries/System.IO.FileSystem/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.IO.FileSystem/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs index 983acfc5489369..feaad06c3e0d2d 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs @@ -10,7 +10,7 @@ public class Directory_Exists : FileSystemTest { #region Utilities - public bool Exists(string path) + public virtual bool Exists(string path) { return Directory.Exists(path); } @@ -57,17 +57,6 @@ public void PathWithInvalidCharactersAsPath_ReturnsFalse(string invalidPath) Assert.False(Exists(TestDirectory + Path.DirectorySeparatorChar + invalidPath)); } - [Fact] - public void PathAlreadyExistsAsFile() - { - string path = GetTestFilePath(); - File.Create(path).Dispose(); - - Assert.False(Exists(IOServices.RemoveTrailingSlash(path))); - Assert.False(Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); - Assert.False(Exists(IOServices.RemoveTrailingSlash(IOServices.AddTrailingSlashIfNeeded(path)))); - } - [Fact] public void PathAlreadyExistsAsDirectory() { @@ -180,18 +169,6 @@ public void ValidExtendedPathExists_ReturnsTrue(string component) Assert.True(Exists(path)); } - [ConditionalFact(nameof(UsingNewNormalization))] - [PlatformSpecific(TestPlatforms.Windows)] // Extended path already exists as file - public void ExtendedPathAlreadyExistsAsFile() - { - string path = IOInputs.ExtendedPrefix + GetTestFilePath(); - File.Create(path).Dispose(); - - Assert.False(Exists(IOServices.RemoveTrailingSlash(path))); - Assert.False(Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); - Assert.False(Exists(IOServices.RemoveTrailingSlash(IOServices.AddTrailingSlashIfNeeded(path)))); - } - [ConditionalFact(nameof(UsingNewNormalization))] [PlatformSpecific(TestPlatforms.Windows)] // Extended path already exists as directory public void ExtendedPathAlreadyExistsAsDirectory() @@ -387,6 +364,34 @@ public void SubdirectoryOnNonExistentDriveAsPath_ReturnsFalse() Assert.False(Exists(Path.Combine(IOServices.GetNonExistentDrive(), "nonexistentsubdir"))); } + #endregion + } + + public class Directory_ExistsAsFile : FileSystemTest + { + [Fact] + public void PathAlreadyExistsAsFile() + { + string path = GetTestFilePath(); + File.Create(path).Dispose(); + + Assert.False(Directory.Exists(IOServices.RemoveTrailingSlash(path))); + Assert.False(Directory.Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); + Assert.False(Directory.Exists(IOServices.RemoveTrailingSlash(IOServices.AddTrailingSlashIfNeeded(path)))); + } + + [ConditionalFact(nameof(UsingNewNormalization))] + [PlatformSpecific(TestPlatforms.Windows)] // Extended path already exists as file + public void ExtendedPathAlreadyExistsAsFile() + { + string path = IOInputs.ExtendedPrefix + GetTestFilePath(); + File.Create(path).Dispose(); + + Assert.False(Directory.Exists(IOServices.RemoveTrailingSlash(path))); + Assert.False(Directory.Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); + Assert.False(Directory.Exists(IOServices.RemoveTrailingSlash(IOServices.AddTrailingSlashIfNeeded(path)))); + } + [Fact] [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser)] // Makes call to native code (libc) public void FalseForNonRegularFile() @@ -395,7 +400,5 @@ public void FalseForNonRegularFile() Assert.Equal(0, mkfifo(fileName, 0)); Assert.False(Directory.Exists(fileName)); } - - #endregion } } diff --git a/src/libraries/System.IO.FileSystem/tests/Enumeration/RootTests.cs b/src/libraries/System.IO.FileSystem/tests/Enumeration/RootTests.cs index e6925ccb8f2c37..501e2011efd3ad 100644 --- a/src/libraries/System.IO.FileSystem/tests/Enumeration/RootTests.cs +++ b/src/libraries/System.IO.FileSystem/tests/Enumeration/RootTests.cs @@ -31,7 +31,7 @@ protected override bool ShouldRecurseIntoEntry(ref FileSystemEntry entry) } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/55821", TestPlatforms.Android)] + [SkipOnPlatform(TestPlatforms.Android, "Test could not work on android since accessing '/' isn't allowed.")] public void CanRecurseFromRoot() { string root = Path.GetPathRoot(Path.GetTempPath()); diff --git a/src/libraries/System.IO.FileSystem/tests/File/Copy.cs b/src/libraries/System.IO.FileSystem/tests/File/Copy.cs index 643d2a98cf22a2..8b1f1c2d4e78cd 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/Copy.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/Copy.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; using Xunit; namespace System.IO.Tests @@ -350,6 +351,21 @@ public void WindowsAlternateDataStreamOverwrite(string defaultStream, string alt Assert.Throws(() => Copy(testFileAlternateStream, testFile2, overwrite: true)); Assert.Throws(() => Copy(testFileAlternateStream, testFile2 + alternateStream, overwrite: true)); } + + [Fact] + public void DestinationFileIsTruncatedWhenItsLargerThanSourceFile() + { + string sourcePath = GetTestFilePath(); + string destPath = GetTestFilePath(); + + byte[] content = RandomNumberGenerator.GetBytes(1000); + File.WriteAllBytes(sourcePath, content); + File.WriteAllBytes(destPath, RandomNumberGenerator.GetBytes(content.Length * 2)); + + Copy(sourcePath, destPath, overwrite: true); + + Assert.Equal(content, File.ReadAllBytes(destPath)); + } } /// diff --git a/src/libraries/System.IO.FileSystem/tests/File/Exists.cs b/src/libraries/System.IO.FileSystem/tests/File/Exists.cs index 1fde8ae98ec7db..ff2c8845bc58a3 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/Exists.cs @@ -52,9 +52,6 @@ public void PathWithInvalidCharactersAsPath_ReturnsFalse(string invalidPath) { // Checks that errors aren't thrown when calling Exists() on paths with impossible to create characters Assert.False(Exists(invalidPath)); - - Assert.False(Exists("..")); - Assert.False(Exists(".")); } [Fact] @@ -100,17 +97,6 @@ public void PathEndsInAltTrailingSlash_AndExists_Windows() Assert.False(Exists(path + Path.AltDirectorySeparatorChar)); } - [Fact] - public void PathAlreadyExistsAsDirectory() - { - string path = GetTestFilePath(); - Directory.CreateDirectory(path); - - Assert.False(Exists(IOServices.RemoveTrailingSlash(path))); - Assert.False(Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); - Assert.False(Exists(IOServices.RemoveTrailingSlash(IOServices.AddTrailingSlashIfNeeded(path)))); - } - [Fact] public void DirectoryLongerThanMaxDirectoryAsPath_DoesntThrow() { @@ -244,6 +230,29 @@ public void DirectoryWithComponentLongerThanMaxComponentAsPath_ReturnsFalse(stri Assert.False(Exists(component)); } + #endregion + } + + public class File_ExistsAsDirectory : FileSystemTest + { + [Fact] + public void DotAsPathReturnsFalse() + { + Assert.False(File.Exists(".")); + Assert.False(File.Exists("..")); + } + + [Fact] + public void PathAlreadyExistsAsDirectory() + { + string path = GetTestFilePath(); + Directory.CreateDirectory(path); + + Assert.False(File.Exists(IOServices.RemoveTrailingSlash(path))); + Assert.False(File.Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); + Assert.False(File.Exists(IOServices.RemoveTrailingSlash(IOServices.AddTrailingSlashIfNeeded(path)))); + } + [Fact] [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser)] // Uses P/Invokes public void FalseForNonRegularFile() @@ -252,7 +261,5 @@ public void FalseForNonRegularFile() Assert.Equal(0, mkfifo(fileName, 0)); Assert.True(File.Exists(fileName)); } - - #endregion } } diff --git a/src/libraries/System.IO.FileSystem/tests/Path/Exists_Directory.cs b/src/libraries/System.IO.FileSystem/tests/Path/Exists_Directory.cs new file mode 100644 index 00000000000000..9c4831d585771e --- /dev/null +++ b/src/libraries/System.IO.FileSystem/tests/Path/Exists_Directory.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.IO.Tests +{ + public class PathDirectory_Exists : Directory_Exists + { + public override bool Exists(string path) => Path.Exists(path); + + [Fact] + public void PathAlreadyExistsAsFile() + { + string path = GetTestFilePath(); + File.Create(path).Dispose(); + + Assert.True(Exists(IOServices.RemoveTrailingSlash(path))); + Assert.True(Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); + Assert.True(Exists(IOServices.RemoveTrailingSlash(IOServices.AddTrailingSlashIfNeeded(path)))); + } + + [ConditionalFact(nameof(UsingNewNormalization))] + [PlatformSpecific(TestPlatforms.Windows)] // Extended path already exists as file + public void ExtendedPathAlreadyExistsAsFile() + { + string path = IOInputs.ExtendedPrefix + GetTestFilePath(); + File.Create(path).Dispose(); + + Assert.True(Exists(IOServices.RemoveTrailingSlash(path))); + Assert.True(Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); + Assert.True(Exists(IOServices.RemoveTrailingSlash(IOServices.AddTrailingSlashIfNeeded(path)))); + } + } +} diff --git a/src/libraries/System.IO.FileSystem/tests/Path/Exists_File.cs b/src/libraries/System.IO.FileSystem/tests/Path/Exists_File.cs new file mode 100644 index 00000000000000..64af8e84c009d2 --- /dev/null +++ b/src/libraries/System.IO.FileSystem/tests/Path/Exists_File.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.IO.Tests +{ + public class PathFile_Exists : File_Exists + { + public override bool Exists(string path) => Path.Exists(path); + + [Fact] + public void PathAlreadyExistsAsDirectory() + { + string path = GetTestFilePath(); + Directory.CreateDirectory(path); + + Assert.True(Exists(IOServices.RemoveTrailingSlash(path))); + Assert.True(Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); + Assert.True(Exists(IOServices.RemoveTrailingSlash(IOServices.AddTrailingSlashIfNeeded(path)))); + } + + [Fact] + [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.Browser)] // Uses P/Invokes + public void TrueForNonRegularFile() + { + string fileName = GetTestFilePath(); + Assert.Equal(0, mkfifo(fileName, 0)); + Assert.True(Exists(fileName)); + } + } +} diff --git a/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj b/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj index 83f7bf47ea78e0..967338535cd01f 100644 --- a/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj +++ b/src/libraries/System.IO.FileSystem/tests/System.IO.FileSystem.Tests.csproj @@ -58,6 +58,8 @@ + + diff --git a/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj b/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj index 1a868fff8a65c6..40664e48643298 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj +++ b/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj @@ -33,11 +33,9 @@ + - - - - - + + diff --git a/src/libraries/System.IO.MemoryMappedFiles/src/Resources/Strings.resx b/src/libraries/System.IO.MemoryMappedFiles/src/Resources/Strings.resx index bdfb97a73c8020..ce321bd41a358a 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/src/Resources/Strings.resx +++ b/src/libraries/System.IO.MemoryMappedFiles/src/Resources/Strings.resx @@ -219,4 +219,7 @@ The path '{0}' is too long, or a component of the specified path is too long. - \ No newline at end of file + + System.IO.MemoryMappedFiles is not supported on this platform. + + diff --git a/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj b/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj index b473091e6ed1bc..87184a69f66fb1 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj +++ b/src/libraries/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj @@ -2,10 +2,14 @@ true enable - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) - - + + + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) + SR.PlatformNotSupported_MemoryMappedFiles + + diff --git a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/PipeWriterStream.cs b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/PipeWriterStream.cs index 67aeadc1bc0e82..22f764979bc629 100644 --- a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/PipeWriterStream.cs +++ b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/PipeWriterStream.cs @@ -24,9 +24,19 @@ protected override void Dispose(bool disposing) { _pipeWriter.Complete(); } - base.Dispose(disposing); } +#if (!NETSTANDARD2_0 && !NETFRAMEWORK) + public override ValueTask DisposeAsync() + { + if (!LeaveOpen) + { + return _pipeWriter.CompleteAsync(); + } + return default; + } +#endif + internal bool LeaveOpen { get; set; } public override bool CanRead => false; diff --git a/src/libraries/System.IO.Pipelines/tests/PipeWriterStreamTests.nonnetstandard.cs b/src/libraries/System.IO.Pipelines/tests/PipeWriterStreamTests.nonnetstandard.cs index 1570fd1ed91474..57f6f8ee1e2eef 100644 --- a/src/libraries/System.IO.Pipelines/tests/PipeWriterStreamTests.nonnetstandard.cs +++ b/src/libraries/System.IO.Pipelines/tests/PipeWriterStreamTests.nonnetstandard.cs @@ -177,10 +177,22 @@ public void AsStreamDoNotCompleteWriter() pipeWriter.AsStream(leaveOpen: true).Dispose(); } + [Fact] + public async Task DisposeAsyncCallsCompleteAsync() + { + var pipeWriter = new TestPipeWriter(); + Stream stream = pipeWriter.AsStream(); + + await stream.DisposeAsync(); + + Assert.True(pipeWriter.CompleteAsyncCalled); + } + public class TestPipeWriter : PipeWriter { public bool FlushCalled { get; set; } public bool WriteAsyncCalled { get; set; } + public bool CompleteAsyncCalled { get; set; } public override void Advance(int bytes) { @@ -197,6 +209,12 @@ public override void Complete(Exception exception = null) throw new NotImplementedException(); } + public override ValueTask CompleteAsync(Exception exception = null) + { + CompleteAsyncCalled = true; + return default; + } + public override ValueTask FlushAsync(CancellationToken cancellationToken = default) { FlushCalled = true; diff --git a/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj b/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj index f43c090d0810bd..5e08c91b938064 100644 --- a/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj +++ b/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj @@ -15,7 +15,8 @@ true - + + diff --git a/src/libraries/System.IO.Pipes/NuGet.config b/src/libraries/System.IO.Pipes/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.IO.Pipes/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj index d597398efb25a5..55437bf7f69bea 100644 --- a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj +++ b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj @@ -162,10 +162,6 @@ - - - - @@ -173,7 +169,9 @@ + + diff --git a/src/libraries/System.IO.Ports/NuGet.config b/src/libraries/System.IO.Ports/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.IO.Ports/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj index d9b6355b234af3..efd034b6044424 100644 --- a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj +++ b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj @@ -4,7 +4,7 @@ $(DefineConstants);SERIAL_PORTS true annotations - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum)-Unix;$(NetCoreAppMinimum);netstandard2.0-windows;netstandard2.0-Unix;netstandard2.0;$(NetFrameworkMinimum) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum)-Unix;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true Provides classes for controlling serial ports. diff --git a/src/libraries/System.IO.UnmanagedMemoryStream/System.IO.UnmanagedMemoryStream.sln b/src/libraries/System.IO.UnmanagedMemoryStream/System.IO.UnmanagedMemoryStream.sln index 21af7492637a93..a275405508be26 100644 --- a/src/libraries/System.IO.UnmanagedMemoryStream/System.IO.UnmanagedMemoryStream.sln +++ b/src/libraries/System.IO.UnmanagedMemoryStream/System.IO.UnmanagedMemoryStream.sln @@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.UnmanagedMemorySt EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.UnmanagedMemoryStream.Tests", "tests\System.IO.UnmanagedMemoryStream.Tests.csproj", "{D14DC8D4-F45E-412D-AE98-CA07F900347B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{5CB1579E-E830-4812-A7F5-0E33E1847BF6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{5CB1579E-E830-4812-A7F5-0E33E1847BF6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{D7A11210-8298-43E5-B414-3019CC7E1A79}" EndProject diff --git a/src/libraries/System.Linq/src/System.Linq.csproj b/src/libraries/System.Linq/src/System.Linq.csproj index 9040f668ab6f1d..4126dfb64148c7 100644 --- a/src/libraries/System.Linq/src/System.Linq.csproj +++ b/src/libraries/System.Linq/src/System.Linq.csproj @@ -98,7 +98,10 @@ + + + \ No newline at end of file diff --git a/src/libraries/System.Linq/src/System/Linq/Average.cs b/src/libraries/System.Linq/src/System/Linq/Average.cs index e204d87cb6159c..da9c9694f8b9cf 100644 --- a/src/libraries/System.Linq/src/System/Linq/Average.cs +++ b/src/libraries/System.Linq/src/System/Linq/Average.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Numerics; namespace System.Linq { @@ -9,9 +10,9 @@ public static partial class Enumerable { public static double Average(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Average(span); } using (IEnumerator e = source.GetEnumerator()) @@ -36,6 +37,38 @@ public static double Average(this IEnumerable source) } } + private static double Average(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + long sum = 0; + int i = 0; + + if (Vector.IsHardwareAccelerated && span.Length >= Vector.Count) + { + Vector sums = default; + do + { + Vector.Widen(new Vector(span.Slice(i)), out Vector low, out Vector high); + sums += low; + sums += high; + i += Vector.Count; + } + while (i <= span.Length - Vector.Count); + sum += Vector.Sum(sums); + } + + for (; (uint)i < (uint)span.Length; i++) + { + sum += span[i]; + } + + return (double)sum / span.Length; + } + public static double? Average(this IEnumerable source) { if (source == null) @@ -75,9 +108,9 @@ public static double Average(this IEnumerable source) public static double Average(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Average(span); } using (IEnumerator e = source.GetEnumerator()) @@ -102,6 +135,22 @@ public static double Average(this IEnumerable source) } } + private static double Average(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + long sum = span[0]; + for (int i = 1; i < span.Length; i++) + { + checked { sum += span[i]; } + } + + return (double)sum / span.Length; + } + public static double? Average(this IEnumerable source) { if (source == null) @@ -141,9 +190,14 @@ public static double Average(this IEnumerable source) public static float Average(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + return (float)(Sum(span) / span.Length); } using (IEnumerator e = source.GetEnumerator()) @@ -204,9 +258,14 @@ public static float Average(this IEnumerable source) public static double Average(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + return Sum(span) / span.Length; } using (IEnumerator e = source.GetEnumerator()) @@ -270,9 +329,14 @@ public static double Average(this IEnumerable source) public static decimal Average(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + return Sum(span) / span.Length; } using (IEnumerator e = source.GetEnumerator()) diff --git a/src/libraries/System.Linq/src/System/Linq/Enumerable.cs b/src/libraries/System.Linq/src/System/Linq/Enumerable.cs index 926113e3069ac0..6e3b2d772609dd 100644 --- a/src/libraries/System.Linq/src/System/Linq/Enumerable.cs +++ b/src/libraries/System.Linq/src/System/Linq/Enumerable.cs @@ -2,11 +2,52 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Linq { public static partial class Enumerable { public static IEnumerable AsEnumerable(this IEnumerable source) => source; + + /// Validates that source is not null and then tries to extract a span from the source. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // fast type checks that don't add a lot of overhead + private static bool TryGetSpan(this IEnumerable source, out ReadOnlySpan span) + // This constraint isn't required, but the overheads involved here can be more substantial when TSource + // is a reference type and generic implementations are shared. So for now we're protecting ourselves + // and forcing a conscious choice to remove this in the future, at which point it should be paired with + // sufficient performance testing. + where TSource : struct + { + if (source is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + } + + // Use `GetType() == typeof(...)` rather than `is` to avoid cast helpers. This is measurably cheaper + // but does mean we could end up missing some rare cases where we could get a span but don't (e.g. a uint[] + // masquerading as an int[]). That's an acceptable tradeoff. The Unsafe usage is only after we've + // validated the exact type; this could be changed to a cast in the future if the JIT starts to recognize it. + // We only pay the comparison/branching costs here for super common types we expect to be used frequently + // with LINQ methods. + + bool result = true; + if (source.GetType() == typeof(TSource[])) + { + span = Unsafe.As(source); + } + else if (source.GetType() == typeof(List)) + { + span = CollectionsMarshal.AsSpan(Unsafe.As>(source)); + } + else + { + span = default; + result = false; + } + + return result; + } } } diff --git a/src/libraries/System.Linq/src/System/Linq/Max.cs b/src/libraries/System.Linq/src/System/Linq/Max.cs index 2c05d2dc29dbbb..8ffe00eb949f3c 100644 --- a/src/libraries/System.Linq/src/System/Linq/Max.cs +++ b/src/libraries/System.Linq/src/System/Linq/Max.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; +using System.Numerics; namespace System.Linq { @@ -10,9 +10,9 @@ public static partial class Enumerable { public static int Max(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Max(span); } int value; @@ -37,6 +37,57 @@ public static int Max(this IEnumerable source) return value; } + private static int Max(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + // Vectorize the search if possible. + int index, value; + if (Vector.IsHardwareAccelerated && span.Length >= Vector.Count * 2) + { + // The span is at least two vectors long. Create a vector from the first N elements, + // and then repeatedly compare that against the next vector from the span. At the end, + // the resulting vector will contain the maximum values found, and we then need only + // to find the max of those. + var maxes = new Vector(span); + index = Vector.Count; + do + { + maxes = Vector.Max(maxes, new Vector(span.Slice(index))); + index += Vector.Count; + } + while (index + Vector.Count <= span.Length); + + value = maxes[0]; + for (int i = 1; i < Vector.Count; i++) + { + if (maxes[i] > value) + { + value = maxes[i]; + } + } + } + else + { + value = span[0]; + index = 1; + } + + // Iterate through the remaining elements, comparing against the max. + for (int i = index; (uint)i < (uint)span.Length; i++) + { + if (span[i] > value) + { + value = span[i]; + } + } + + return value; + } + public static int? Max(this IEnumerable source) { if (source == null) @@ -101,9 +152,9 @@ public static int Max(this IEnumerable source) public static long Max(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Max(span); } long value; @@ -128,6 +179,58 @@ public static long Max(this IEnumerable source) return value; } + private static long Max(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + // Vectorize the search if possible. + int index; + long value; + if (Vector.IsHardwareAccelerated && span.Length >= Vector.Count * 2) + { + // The span is at least two vectors long. Create a vector from the first N elements, + // and then repeatedly compare that against the next vector from the span. At the end, + // the resulting vector will contain the maximum values found, and we then need only + // to find the max of those. + var maxes = new Vector(span); + index = Vector.Count; + do + { + maxes = Vector.Max(maxes, new Vector(span.Slice(index))); + index += Vector.Count; + } + while (index + Vector.Count <= span.Length); + + value = maxes[0]; + for (int i = 1; i < Vector.Count; i++) + { + if (maxes[i] > value) + { + value = maxes[i]; + } + } + } + else + { + value = span[0]; + index = 1; + } + + // Iterate through the remaining elements, comparing against the max. + for (int i = index; (uint)i < (uint)span.Length; i++) + { + if (span[i] > value) + { + value = span[i]; + } + } + + return value; + } + public static long? Max(this IEnumerable source) { if (source == null) @@ -186,9 +289,9 @@ public static long Max(this IEnumerable source) public static double Max(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Max(span); } double value; @@ -228,6 +331,33 @@ public static double Max(this IEnumerable source) return value; } + private static double Max(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + int i; + for (i = 0; i < span.Length && double.IsNaN(span[i]); i++); + + if (i == span.Length) + { + return span[^1]; + } + + double value; + for (value = span[i]; (uint)i < (uint)span.Length; i++) + { + if (span[i] > value) + { + value = span[i]; + } + } + + return value; + } + public static double? Max(this IEnumerable source) { if (source == null) @@ -284,9 +414,9 @@ public static double Max(this IEnumerable source) public static float Max(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Max(span); } float value; @@ -321,6 +451,33 @@ public static float Max(this IEnumerable source) return value; } + private static float Max(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + int i; + for (i = 0; i < span.Length && float.IsNaN(span[i]); i++); + + if (i == span.Length) + { + return span[^1]; + } + + float value; + for (value = span[i]; (uint)i < (uint)span.Length; i++) + { + if (span[i] > value) + { + value = span[i]; + } + } + + return value; + } + public static float? Max(this IEnumerable source) { if (source == null) @@ -377,9 +534,9 @@ public static float Max(this IEnumerable source) public static decimal Max(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Max(span); } decimal value; @@ -404,6 +561,25 @@ public static decimal Max(this IEnumerable source) return value; } + private static decimal Max(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + decimal value = span[0]; + for (int i = 1; (uint)i < (uint)span.Length; i++) + { + if (span[i] > value) + { + value = span[i]; + } + } + + return value; + } + public static decimal? Max(this IEnumerable source) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Min.cs b/src/libraries/System.Linq/src/System/Linq/Min.cs index 9f9266ff1bb83b..e97e8674914dbe 100644 --- a/src/libraries/System.Linq/src/System/Linq/Min.cs +++ b/src/libraries/System.Linq/src/System/Linq/Min.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; +using System.Numerics; namespace System.Linq { @@ -10,9 +10,9 @@ public static partial class Enumerable { public static int Min(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Min(span); } int value; @@ -37,6 +37,57 @@ public static int Min(this IEnumerable source) return value; } + private static int Min(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + // Vectorize the search if possible. + int index, value; + if (Vector.IsHardwareAccelerated && span.Length >= Vector.Count * 2) + { + // The span is at least two vectors long. Create a vector from the first N elements, + // and then repeatedly compare that against the next vector from the span. At the end, + // the resulting vector will contain the minimum values found, and we then need only + // to find the min of those. + var mins = new Vector(span); + index = Vector.Count; + do + { + mins = Vector.Min(mins, new Vector(span.Slice(index))); + index += Vector.Count; + } + while (index + Vector.Count <= span.Length); + + value = mins[0]; + for (int i = 1; i < Vector.Count; i++) + { + if (mins[i] < value) + { + value = mins[i]; + } + } + } + else + { + value = span[0]; + index = 1; + } + + // Iterate through the remaining elements, comparing against the min. + for (int i = index; (uint)i < (uint)span.Length; i++) + { + if (span[i] < value) + { + value = span[i]; + } + } + + return value; + } + public static int? Min(this IEnumerable source) { if (source == null) @@ -83,9 +134,9 @@ public static int Min(this IEnumerable source) public static long Min(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Min(span); } long value; @@ -110,6 +161,58 @@ public static long Min(this IEnumerable source) return value; } + private static long Min(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + // Vectorize the search if possible. + int index; + long value; + if (Vector.IsHardwareAccelerated && span.Length >= Vector.Count * 2) + { + // The span is at least two vectors long. Create a vector from the first N elements, + // and then repeatedly compare that against the next vector from the span. At the end, + // the resulting vector will contain the minimum values found, and we then need only + // to find the min of those. + var mins = new Vector(span); + index = Vector.Count; + do + { + mins = Vector.Min(mins, new Vector(span.Slice(index))); + index += Vector.Count; + } + while (index + Vector.Count <= span.Length); + + value = mins[0]; + for (int i = 1; i < Vector.Count; i++) + { + if (mins[i] < value) + { + value = mins[i]; + } + } + } + else + { + value = span[0]; + index = 1; + } + + // Iterate through the remaining elements, comparing against the min. + for (int i = index; (uint)i < (uint)span.Length; i++) + { + if (span[i] < value) + { + value = span[i]; + } + } + + return value; + } + public static long? Min(this IEnumerable source) { if (source == null) @@ -152,9 +255,9 @@ public static long Min(this IEnumerable source) public static float Min(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Min(span); } float value; @@ -197,6 +300,30 @@ public static float Min(this IEnumerable source) return value; } + private static float Min(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + float value = span[0]; + for (int i = 1; (uint)i < (uint)span.Length; i++) + { + float f = span[i]; + if (f < value) + { + value = f; + } + else if (float.IsNaN(f)) + { + return f; + } + } + + return value; + } + public static float? Min(this IEnumerable source) { if (source == null) @@ -248,9 +375,9 @@ public static float Min(this IEnumerable source) public static double Min(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Min(span); } double value; @@ -284,6 +411,30 @@ public static double Min(this IEnumerable source) return value; } + private static double Min(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + double value = span[0]; + for (int i = 1; (uint)i < (uint)span.Length; i++) + { + double d = span[i]; + if (d < value) + { + value = d; + } + else if (double.IsNaN(d)) + { + return d; + } + } + + return value; + } + public static double? Min(this IEnumerable source) { if (source == null) @@ -335,9 +486,9 @@ public static double Min(this IEnumerable source) public static decimal Min(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Min(span); } decimal value; @@ -362,6 +513,25 @@ public static decimal Min(this IEnumerable source) return value; } + private static decimal Min(ReadOnlySpan span) + { + if (span.IsEmpty) + { + ThrowHelper.ThrowNoElementsException(); + } + + decimal value = span[0]; + for (int i = 1; (uint)i < (uint)span.Length; i++) + { + if (span[i] < value) + { + value = span[i]; + } + } + + return value; + } + public static decimal? Min(this IEnumerable source) { if (source == null) diff --git a/src/libraries/System.Linq/src/System/Linq/Sum.cs b/src/libraries/System.Linq/src/System/Linq/Sum.cs index ece04bc8a27e9c..a54d116c53f301 100644 --- a/src/libraries/System.Linq/src/System/Linq/Sum.cs +++ b/src/libraries/System.Linq/src/System/Linq/Sum.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Numerics; namespace System.Linq { @@ -9,17 +10,19 @@ public static partial class Enumerable { public static int Sum(this IEnumerable source) { - if (source == null) + int sum = 0; + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + foreach (int v in span) + { + checked { sum += v; } + } } - - int sum = 0; - checked + else { foreach (int v in source) { - sum += v; + checked { sum += v; } } } @@ -50,17 +53,19 @@ public static int Sum(this IEnumerable source) public static long Sum(this IEnumerable source) { - if (source == null) + long sum = 0; + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + foreach (long v in span) + { + checked { sum += v; } + } } - - long sum = 0; - checked + else { foreach (long v in source) { - sum += v; + checked { sum += v; } } } @@ -91,9 +96,9 @@ public static long Sum(this IEnumerable source) public static float Sum(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return (float)Sum(span); } double sum = 0; @@ -105,6 +110,18 @@ public static float Sum(this IEnumerable source) return (float)sum; } + private static double Sum(ReadOnlySpan span) + { + double sum = 0; + + for (int i = 0; i < span.Length; i++) + { + sum += span[i]; + } + + return sum; + } + public static float? Sum(this IEnumerable source) { if (source == null) @@ -126,15 +143,27 @@ public static float Sum(this IEnumerable source) public static double Sum(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Sum(span); } double sum = 0; - foreach (double v in source) + foreach (double d in source) { - sum += v; + sum += d; + } + + return sum; + } + + private static double Sum(ReadOnlySpan span) + { + double sum = 0; + + for (int i = 0; i < span.Length; i++) + { + sum += span[i]; } return sum; @@ -161,20 +190,30 @@ public static double Sum(this IEnumerable source) public static decimal Sum(this IEnumerable source) { - if (source == null) + if (source.TryGetSpan(out ReadOnlySpan span)) { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); + return Sum(span); } decimal sum = 0; - foreach (decimal v in source) + foreach (decimal d in source) { - sum += v; + sum += d; } return sum; } + private static decimal Sum(ReadOnlySpan span) + { + decimal sum = 0; + foreach (decimal d in span) + { + sum += d; + } + return sum; + } + public static decimal? Sum(this IEnumerable source) { if (source == null) diff --git a/src/libraries/System.Linq/tests/AverageTests.cs b/src/libraries/System.Linq/tests/AverageTests.cs index 461639a1df5fe4..0ca25ce914dfb6 100644 --- a/src/libraries/System.Linq/tests/AverageTests.cs +++ b/src/libraries/System.Linq/tests/AverageTests.cs @@ -85,10 +85,17 @@ public void NullableFloat_WithSelector() [Fact] public void Int_EmptySource_ThrowsInvalidOperationException() { - int[] source = new int[0]; - - Assert.Throws(() => source.Average()); - Assert.Throws(() => source.Average(i => i)); + foreach (IEnumerable source in new IEnumerable[] + { + Array.Empty(), + new List(), + Enumerable.Empty(), + new TestEnumerable(Array.Empty()) + }) + { + Assert.Throws(() => source.Average()); + Assert.Throws(() => source.Average(i => i)); + } } [Fact] @@ -110,18 +117,28 @@ public static IEnumerable Int_TestData() yield return new object[] { new int[] { 5 }, 5 }; yield return new object[] { new int[] { 0, 0, 0, 0, 0 }, 0 }; yield return new object[] { new int[] { 5, -10, 15, 40, 28 }, 15.6 }; + + for (int i = 1; i <= 33; i++) + { + int sum = 0; + for (int c = 1; c <= i; c++) sum += c; + double expected = (double)sum / i; + + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i)), expected }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i).ToArray()), expected }; + } } [Theory] [MemberData(nameof(Int_TestData))] - public void Int(int[] source, double expected) + public void Int(IEnumerable source, double expected) { Assert.Equal(expected, source.Average()); Assert.Equal(expected, source.Average(x => x)); } [Theory, MemberData(nameof(Int_TestData))] - public void IntRunOnce(int[] source, double expected) + public void IntRunOnce(IEnumerable source, double expected) { Assert.Equal(expected, source.RunOnce().Average()); Assert.Equal(expected, source.RunOnce().Average(x => x)); @@ -190,10 +207,17 @@ public void NullableInt_WithSelector() [Fact] public void Long_EmptySource_ThrowsInvalidOperationException() { - long[] source = new long[0]; - - Assert.Throws(() => source.Average()); - Assert.Throws(() => source.Average(i => i)); + foreach (IEnumerable source in new IEnumerable[] + { + Array.Empty(), + new List(), + Enumerable.Empty(), + new TestEnumerable(Array.Empty()) + }) + { + Assert.Throws(() => source.Average()); + Assert.Throws(() => source.Average(i => i)); + } } [Fact] @@ -215,11 +239,21 @@ public static IEnumerable Long_TestData() yield return new object[] { new long[] { long.MaxValue }, long.MaxValue }; yield return new object[] { new long[] { 0, 0, 0, 0, 0 }, 0 }; yield return new object[] { new long[] { 5, -10, 15, 40, 28 }, 15.6 }; + + for (int i = 1; i <= 33; i++) + { + int sum = 0; + for (int c = 1; c <= i; c++) sum += c; + double expected = (double)sum / i; + + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i).Select(i => (long)i)), expected }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i).Select(i => (long)i).ToArray()), expected }; + } } [Theory] [MemberData(nameof(Long_TestData))] - public void Long(long[] source, double expected) + public void Long(IEnumerable source, double expected) { Assert.Equal(expected, source.Average()); Assert.Equal(expected, source.Average(x => x)); @@ -296,10 +330,17 @@ public void NullableLong_WithSelector() [Fact] public void Double_EmptySource_ThrowsInvalidOperationException() { - double[] source = new double[0]; - - Assert.Throws(() => source.Average()); - Assert.Throws(() => source.Average(i => i)); + foreach (IEnumerable source in new IEnumerable[] + { + Array.Empty(), + new List(), + Enumerable.Empty(), + new TestEnumerable(Array.Empty()) + }) + { + Assert.Throws(() => source.Average()); + Assert.Throws(() => source.Average(i => i)); + } } [Fact] @@ -322,11 +363,21 @@ public static IEnumerable Double_TestData() yield return new object[] { new double[] { 0.0, 0.0, 0.0, 0.0, 0.0 }, 0 }; yield return new object[] { new double[] { 5.5, -10, 15.5, 40.5, 28.5 }, 16 }; yield return new object[] { new double[] { 5.58, double.NaN, 30, 4.55, 19.38 }, double.NaN }; + + for (int i = 1; i <= 33; i++) + { + int sum = 0; + for (int c = 1; c <= i; c++) sum += c; + double expected = (double)sum / i; + + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i).Select(i => (double)i)), expected }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i).Select(i => (double)i).ToArray()), expected }; + } } [Theory] [MemberData(nameof(Double_TestData))] - public void Average_Double(double[] source, double expected) + public void Average_Double(IEnumerable source, double expected) { Assert.Equal(expected, source.Average()); Assert.Equal(expected, source.Average(x => x)); @@ -396,10 +447,17 @@ public void NullableDouble_WithSelector() [Fact] public void Decimal_EmptySource_ThrowsInvalidOperationException() { - decimal[] source = new decimal[0]; - - Assert.Throws(() => source.Average()); - Assert.Throws(() => source.Average(i => i)); + foreach (IEnumerable source in new IEnumerable[] + { + Array.Empty(), + new List(), + Enumerable.Empty(), + new TestEnumerable(Array.Empty()) + }) + { + Assert.Throws(() => source.Average()); + Assert.Throws(() => source.Average(i => i)); + } } [Fact] @@ -421,11 +479,21 @@ public static IEnumerable Decimal_TestData() yield return new object[] { new decimal[] { decimal.MaxValue }, decimal.MaxValue }; yield return new object[] { new decimal[] { 0.0m, 0.0m, 0.0m, 0.0m, 0.0m }, 0 }; yield return new object[] { new decimal[] { 5.5m, -10m, 15.5m, 40.5m, 28.5m }, 16 }; + + for (int i = 1; i <= 33; i++) + { + int sum = 0; + for (int c = 1; c <= i; c++) sum += c; + decimal expected = (decimal)sum / i; + + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i).Select(i => (decimal)i)), expected }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i).Select(i => (decimal)i).ToArray()), expected }; + } } [Theory] [MemberData(nameof(Decimal_TestData))] - public void Decimal(decimal[] source, decimal expected) + public void Decimal(IEnumerable source, decimal expected) { Assert.Equal(expected, source.Average()); Assert.Equal(expected, source.Average(x => x)); @@ -502,10 +570,17 @@ public void NullableDecimal_SumTooLarge_ThrowsOverflowException() [Fact] public void Float_EmptySource_ThrowsInvalidOperationException() { - float[] source = new float[0]; - - Assert.Throws(() => source.Average()); - Assert.Throws(() => source.Average(i => i)); + foreach (IEnumerable source in new IEnumerable[] + { + Array.Empty(), + new List(), + Enumerable.Empty(), + new TestEnumerable(Array.Empty()) + }) + { + Assert.Throws(() => source.Average()); + Assert.Throws(() => source.Average(i => i)); + } } [Fact] @@ -527,11 +602,21 @@ public static IEnumerable Float_TestData() yield return new object[] { new float[] { float.MaxValue }, float.MaxValue }; yield return new object[] { new float[] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, 0f }; yield return new object[] { new float[] { 5.5f, -10f, 15.5f, 40.5f, 28.5f }, 16f }; + + for (int i = 1; i <= 33; i++) + { + int sum = 0; + for (int c = 1; c <= i; c++) sum += c; + float expected = (float)sum / i; + + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i).Select(i => (float)i)), expected }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(1, i).Select(i => (float)i).ToArray()), expected }; + } } [Theory] [MemberData(nameof(Float_TestData))] - public void Float(float[] source, float expected) + public void Float(IEnumerable source, float expected) { Assert.Equal(expected, source.Average()); Assert.Equal(expected, source.Average(x => x)); diff --git a/src/libraries/System.Linq/tests/MaxTests.cs b/src/libraries/System.Linq/tests/MaxTests.cs index 78318b64b1194e..c3d058161fb2d7 100644 --- a/src/libraries/System.Linq/tests/MaxTests.cs +++ b/src/libraries/System.Linq/tests/MaxTests.cs @@ -40,21 +40,36 @@ public void Max_Int_EmptySource_ThrowsInvalidOpertionException() { Assert.Throws(() => Enumerable.Empty().Max()); Assert.Throws(() => Enumerable.Empty().Max(x => x)); + Assert.Throws(() => Array.Empty().Max()); + Assert.Throws(() => new List().Max()); } public static IEnumerable Max_Int_TestData() { - yield return new object[] { Enumerable.Repeat(42, 1), 42 }; - yield return new object[] { Enumerable.Range(1, 10).ToArray(), 10 }; - yield return new object[] { new int[] { -100, -15, -50, -10 }, -10 }; - yield return new object[] { new int[] { -16, 0, 50, 100, 1000 }, 1000 }; - yield return new object[] { new int[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(int.MaxValue, 1)), int.MaxValue }; + foreach ((int[] array, long expected) in new[] + { + (new[] { 42 }, 42), + (Enumerable.Range(1, 10).ToArray(), 10), + (new int[] { -100, -15, -50, -10 }, -10), + (new int[] { -16, 0, 50, 100, 1000 }, 1000), + (new int[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(int.MaxValue, 1)).ToArray(), int.MaxValue), + + (new[] { 20 }, 20), + (Enumerable.Repeat(-2, 5).ToArray(), -2), + (new int[] { 16, 9, 10, 7, 8 }, 16), + (new int[] { 6, 9, 10, 0, 50 }, 50), + (new int[] { -6, 0, -9, 0, -10, 0 }, 0), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } - yield return new object[] { Enumerable.Repeat(20, 1), 20 }; - yield return new object[] { Enumerable.Repeat(-2, 5), -2 }; - yield return new object[] { new int[] { 16, 9, 10, 7, 8 }, 16 }; - yield return new object[] { new int[] { 6, 9, 10, 0, 50 }, 50 }; - yield return new object[] { new int[] { -6, 0, -9, 0, -10, 0 }, 0 }; + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length)), length + length - 1 }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).ToArray()), length + length - 1 }; + } } [Theory] @@ -67,17 +82,30 @@ public void Max_Int(IEnumerable source, int expected) public static IEnumerable Max_Long_TestData() { - yield return new object[] { Enumerable.Repeat(42L, 1), 42L }; - yield return new object[] { Enumerable.Range(1, 10).Select(i => (long)i).ToArray(), 10L }; - yield return new object[] { new long[] { -100, -15, -50, -10 }, -10L }; - yield return new object[] { new long[] { -16, 0, 50, 100, 1000 }, 1000L }; - yield return new object[] { new long[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(long.MaxValue, 1)), long.MaxValue }; + foreach ((long[] array, long expected) in new[] + { + (new[] { 42L }, 42L), + (Enumerable.Range(1, 10).Select(i => (long)i).ToArray(), 10L), + (new long[] { -100, -15, -50, -10 }, -10L), + (new long[] { -16, 0, 50, 100, 1000 }, 1000L), + (new long[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(long.MaxValue, 1)).ToArray(), long.MaxValue), + + (new[] { int.MaxValue + 10L }, int.MaxValue + 10L), + (Enumerable.Repeat(500L, 5).ToArray(), 500L), + (new long[] { 250, 49, 130, 47, 28 }, 250L), + (new long[] { 6, 9, 10, 0, int.MaxValue + 50L }, int.MaxValue + 50L), + (new long[] { 6, 50, 9, 50, 10, 50 }, 50L), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } - yield return new object[] { Enumerable.Repeat(int.MaxValue + 10L, 1), int.MaxValue + 10L }; - yield return new object[] { Enumerable.Repeat(500L, 5), 500L }; - yield return new object[] { new long[] { 250, 49, 130, 47, 28 }, 250L }; - yield return new object[] { new long[] { 6, 9, 10, 0, int.MaxValue + 50L }, int.MaxValue + 50L }; - yield return new object[] { new long[] { 6, 50, 9, 50, 10, 50 }, 50L }; + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (long)i)), (long)(length + length - 1) }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (long)i).ToArray()), (long)(length + length - 1) }; + } } [Theory] @@ -100,36 +128,51 @@ public void Max_Long_EmptySource_ThrowsInvalidOpertionException() { Assert.Throws(() => Enumerable.Empty().Max()); Assert.Throws(() => Enumerable.Empty().Max(x => x)); + Assert.Throws(() => Array.Empty().Max()); + Assert.Throws(() => new List().Max()); } public static IEnumerable Max_Float_TestData() { - yield return new object[] { Enumerable.Repeat(42f, 1), 42f }; - yield return new object[] { Enumerable.Range(1, 10).Select(i => (float)i).ToArray(), 10f }; - yield return new object[] { new float[] { -100, -15, -50, -10 }, -10f }; - yield return new object[] { new float[] { -16, 0, 50, 100, 1000 }, 1000f }; - yield return new object[] { new float[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(float.MaxValue, 1)), float.MaxValue }; - - yield return new object[] { Enumerable.Repeat(5.5f, 1), 5.5f }; - yield return new object[] { new float[] { 112.5f, 4.9f, 30f, 4.7f, 28f }, 112.5f }; - yield return new object[] { new float[] { 6.8f, 9.4f, -10f, 0f, float.NaN, 53.6f }, 53.6f }; - yield return new object[] { new float[] { -5.5f, float.PositiveInfinity, 9.9f, float.PositiveInfinity }, float.PositiveInfinity }; - - yield return new object[] { Enumerable.Repeat(float.NaN, 5), float.NaN }; - yield return new object[] { new float[] { float.NaN, 6.8f, 9.4f, 10f, 0, -5.6f }, 10f }; - yield return new object[] { new float[] { 6.8f, 9.4f, 10f, 0, -5.6f, float.NaN }, 10f }; - yield return new object[] { new float[] { float.NaN, float.NegativeInfinity }, float.NegativeInfinity }; - yield return new object[] { new float[] { float.NegativeInfinity, float.NaN }, float.NegativeInfinity }; - - // Normally NaN < anything and anything < NaN returns false - // However, this leads to some irksome outcomes in Min and Max. - // If we use those semantics then Min(NaN, 5.0) is NaN, but - // Min(5.0, NaN) is 5.0! To fix this, we impose a total - // ordering where NaN is smaller than every value, including - // negative infinity. - yield return new object[] { Enumerable.Range(1, 10).Select(i => (float)i).Concat(Enumerable.Repeat(float.NaN, 1)).ToArray(), 10f }; - yield return new object[] { new float[] { -1f, -10, float.NaN, 10, 200, 1000 }, 1000f }; - yield return new object[] { new float[] { float.MinValue, 3000f, 100, 200, float.NaN, 1000 }, 3000f }; + foreach ((float[] array, float expected) in new[] + { + (new[] { 42f }, 42f), + (Enumerable.Range(1, 10).Select(i => (float)i).ToArray(), 10f), + (new float[] { -100, -15, -50, -10 }, -10f), + (new float[] { -16, 0, 50, 100, 1000 }, 1000f), + (new float[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(float.MaxValue, 1)).ToArray(), float.MaxValue), + + (new[] { 5.5f }, 5.5f), + (new float[] { 112.5f, 4.9f, 30f, 4.7f, 28f }, 112.5f), + (new float[] { 6.8f, 9.4f, -10f, 0f, float.NaN, 53.6f }, 53.6f), + (new float[] { -5.5f, float.PositiveInfinity, 9.9f, float.PositiveInfinity }, float.PositiveInfinity), + + (Enumerable.Repeat(float.NaN, 5).ToArray(), float.NaN), + (new float[] { float.NaN, 6.8f, 9.4f, 10f, 0, -5.6f }, 10f), + (new float[] { 6.8f, 9.4f, 10f, 0, -5.6f, float.NaN }, 10f), + (new float[] { float.NaN, float.NegativeInfinity }, float.NegativeInfinity), + (new float[] { float.NegativeInfinity, float.NaN }, float.NegativeInfinity), + + // Normally NaN < anything and anything < NaN returns false + // However, this leads to some irksome outcomes in Min and Max. + // If we use those semantics then Min(NaN, 5.0) is NaN, but + // Min(5.0, NaN) is 5.0! To fix this, we impose a total + // ordering where NaN is smaller than every value, including + // negative infinity. + (Enumerable.Range(1, 10).Select(i => (float)i).Concat(Enumerable.Repeat(float.NaN, 1)).ToArray(), 10f), + (new float[] { -1f, -10, float.NaN, 10, 200, 1000 }, 1000f), + (new float[] { float.MinValue, 3000f, 100, 200, float.NaN, 1000 }, 3000f), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } + + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (float)i)), (float)(length + length - 1) }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (float)i).ToArray()), (float)(length + length - 1) }; + } } [Theory] @@ -176,31 +219,44 @@ public void Max_Float_NaNAtStartWithSelector() public static IEnumerable Max_Double_TestData() { - yield return new object[] { Enumerable.Repeat(42.0, 1), 42.0 }; - yield return new object[] { Enumerable.Range(1, 10).Select(i => (double)i).ToArray(), 10.0 }; - yield return new object[] { new double[] { -100, -15, -50, -10 }, -10.0 }; - yield return new object[] { new double[] { -16, 0, 50, 100, 1000 }, 1000.0 }; - yield return new object[] { new double[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(double.MaxValue, 1)), double.MaxValue }; - - yield return new object[] { Enumerable.Repeat(5.5, 1), 5.5 }; - yield return new object[] { Enumerable.Repeat(double.NaN, 5), double.NaN }; - yield return new object[] { new double[] { 112.5, 4.9, 30, 4.7, 28 }, 112.5 }; - yield return new object[] { new double[] { 6.8, 9.4, -10, 0, double.NaN, 53.6 }, 53.6 }; - yield return new object[] { new double[] { -5.5, double.PositiveInfinity, 9.9, double.PositiveInfinity }, double.PositiveInfinity }; - yield return new object[] { new double[] { double.NaN, 6.8, 9.4, 10.5, 0, -5.6 }, 10.5 }; - yield return new object[] { new double[] { 6.8, 9.4, 10.5, 0, -5.6, double.NaN }, 10.5 }; - yield return new object[] { new double[] { double.NaN, double.NegativeInfinity }, double.NegativeInfinity }; - yield return new object[] { new double[] { double.NegativeInfinity, double.NaN }, double.NegativeInfinity }; - - // Normally NaN < anything and anything < NaN returns false - // However, this leads to some irksome outcomes in Min and Max. - // If we use those semantics then Min(NaN, 5.0) is NaN, but - // Min(5.0, NaN) is 5.0! To fix this, we impose a total - // ordering where NaN is smaller than every value, including - // negative infinity. - yield return new object[] { Enumerable.Range(1, 10).Select(i => (double)i).Concat(Enumerable.Repeat(double.NaN, 1)).ToArray(), 10.0 }; - yield return new object[] { new double[] { -1F, -10, double.NaN, 10, 200, 1000 }, 1000.0 }; - yield return new object[] { new double[] { double.MinValue, 3000F, 100, 200, double.NaN, 1000 }, 3000.0 }; + foreach ((double[] array, double expected) in new[] + { + (new[] { 42.0 }, 42.0), + (Enumerable.Range(1, 10).Select(i => (double)i).ToArray(), 10.0), + (new double[] { -100, -15, -50, -10 }, -10.0), + (new double[] { -16, 0, 50, 100, 1000 }, 1000.0), + (new double[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(double.MaxValue, 1)).ToArray(), double.MaxValue), + + (Enumerable.Repeat(5.5, 1).ToArray(), 5.5), + (Enumerable.Repeat(double.NaN, 5).ToArray(), double.NaN), + (new double[] { 112.5, 4.9, 30, 4.7, 28 }, 112.5), + (new double[] { 6.8, 9.4, -10, 0, double.NaN, 53.6 }, 53.6), + (new double[] { -5.5, double.PositiveInfinity, 9.9, double.PositiveInfinity }, double.PositiveInfinity), + (new double[] { double.NaN, 6.8, 9.4, 10.5, 0, -5.6 }, 10.5), + (new double[] { 6.8, 9.4, 10.5, 0, -5.6, double.NaN }, 10.5), + (new double[] { double.NaN, double.NegativeInfinity }, double.NegativeInfinity), + (new double[] { double.NegativeInfinity, double.NaN }, double.NegativeInfinity), + + // Normally NaN < anything and anything < NaN returns false + // However, this leads to some irksome outcomes in Min and Max. + // If we use those semantics then Min(NaN, 5.0) is NaN, but + // Min(5.0, NaN) is 5.0! To fix this, we impose a total + // ordering where NaN is smaller than every value, including + // negative infinity. + (Enumerable.Range(1, 10).Select(i => (double)i).Concat(Enumerable.Repeat(double.NaN, 1)).ToArray(), 10.0), + (new double[] { -1F, -10, double.NaN, 10, 200, 1000 }, 1000.0), + (new double[] { double.MinValue, 3000F, 100, 200, double.NaN, 1000 }, 3000.0), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } + + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (double)i)), (double)(length + length - 1) }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (double)i).ToArray()), (double)(length + length - 1) }; + } } [Theory] @@ -247,17 +303,30 @@ public void Max_Double_NaNThenNegativeInfinityWithSelector() public static IEnumerable Max_Decimal_TestData() { - yield return new object[] { Enumerable.Repeat(42m, 1), 42m }; - yield return new object[] { Enumerable.Range(1, 10).Select(i => (decimal)i).ToArray(), 10m }; - yield return new object[] { new decimal[] { -100, -15, -50, -10 }, -10m }; - yield return new object[] { new decimal[] { -16, 0, 50, 100, 1000 }, 1000m }; - yield return new object[] { new decimal[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(decimal.MaxValue, 1)), decimal.MaxValue }; + foreach ((decimal[] array, decimal expected) in new[] + { + (new[] { 42m }, 42m), + (Enumerable.Range(1, 10).Select(i => (decimal)i).ToArray(), 10m), + (new decimal[] { -100, -15, -50, -10 }, -10m), + (new decimal[] { -16, 0, 50, 100, 1000 }, 1000m), + (new decimal[] { -16, 0, 50, 100, 1000 }.Concat(Enumerable.Repeat(decimal.MaxValue, 1)).ToArray(), decimal.MaxValue), + + (new decimal[] { 5.5m }, 5.5m), + (Enumerable.Repeat(-3.4m, 5).ToArray(), -3.4m), + (new decimal[] { 122.5m, 4.9m, 10m, 4.7m, 28m }, 122.5m), + (new decimal[] { 6.8m, 9.4m, 10m, 0m, 0m, decimal.MaxValue }, decimal.MaxValue), + (new decimal[] { -5.5m, 0m, 9.9m, -5.5m, 9.9m }, 9.9m), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } - yield return new object[] { new decimal[] { 5.5m }, 5.5m }; - yield return new object[] { Enumerable.Repeat(-3.4m, 5), -3.4m }; - yield return new object[] { new decimal[] { 122.5m, 4.9m, 10m, 4.7m, 28m }, 122.5m }; - yield return new object[] { new decimal[] { 6.8m, 9.4m, 10m, 0m, 0m, decimal.MaxValue }, decimal.MaxValue }; - yield return new object[] { new decimal[] { -5.5m, 0m, 9.9m, -5.5m, 9.9m }, 9.9m }; + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (decimal)i)), (decimal)(length + length - 1) }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (decimal)i).ToArray()), (decimal)(length + length - 1) }; + } } [Theory] @@ -280,6 +349,8 @@ public void Max_Decimal_EmptySource_ThrowsInvalidOperationException() { Assert.Throws(() => Enumerable.Empty().Max()); Assert.Throws(() => Enumerable.Empty().Max(x => x)); + Assert.Throws(() => Array.Empty().Max()); + Assert.Throws(() => new List().Max(x => x)); } public static IEnumerable Max_NullableInt_TestData() diff --git a/src/libraries/System.Linq/tests/MinTests.cs b/src/libraries/System.Linq/tests/MinTests.cs index 31296da12c6918..c8165596735470 100644 --- a/src/libraries/System.Linq/tests/MinTests.cs +++ b/src/libraries/System.Linq/tests/MinTests.cs @@ -30,18 +30,31 @@ public void SameResultsRepeatCallsStringQuery() public static IEnumerable Min_Int_TestData() { - yield return new object[] { Enumerable.Repeat(42, 1), 42 }; - yield return new object[] { Enumerable.Range(1, 10).ToArray(), 1 }; - yield return new object[] { new int[] { -1, -10, 10, 200, 1000 }, -10 }; - yield return new object[] { new int[] { 3000, 100, 200, 1000 }, 100 }; - yield return new object[] { new int[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(int.MinValue, 1)), int.MinValue }; + foreach ((int[] array, long expected) in new[] + { + (new[] { 42 }, 42), + (Enumerable.Range(1, 10).ToArray(), 1), + (new int[] { -1, -10, 10, 200, 1000 }, -10), + (new int[] { 3000, 100, 200, 1000 }, 100), + (new int[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(int.MinValue, 1)).ToArray(), int.MinValue), + + (new[] { 20 }, 20), + (Enumerable.Repeat(-2, 5).ToArray(), -2), + (Enumerable.Range(1, 10).ToArray(), 1), + (new int[] { 6, 9, 10, 7, 8 }, 6), + (new int[] { 6, 9, 10, 0, -5 }, -5), + (new int[] { 6, 0, 9, 0, 10, 0 }, 0), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } - yield return new object[] { Enumerable.Repeat(20, 1), 20 }; - yield return new object[] { Enumerable.Repeat(-2, 5), -2 }; - yield return new object[] { Enumerable.Range(1, 10).ToArray(), 1 }; - yield return new object[] { new int[] { 6, 9, 10, 7, 8 }, 6 }; - yield return new object[] { new int[] { 6, 9, 10, 0, -5 }, -5 }; - yield return new object[] { new int[] { 6, 0, 9, 0, 10, 0 }, 0 }; + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length)), length }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).ToArray()), length }; + } } [Theory] @@ -64,21 +77,36 @@ public void Min_Int_EmptySource_ThrowsInvalidOperationException() { Assert.Throws(() => Enumerable.Empty().Min()); Assert.Throws(() => Enumerable.Empty().Min(x => x)); + Assert.Throws(() => Array.Empty().Min()); + Assert.Throws(() => new List().Min()); } public static IEnumerable Min_Long_TestData() { - yield return new object[] { Enumerable.Repeat(42L, 1), 42L }; - yield return new object[] { Enumerable.Range(1, 10).Select(i => (long)i).ToArray(), 1L }; - yield return new object[] { new long[] { -1, -10, 10, 200, 1000 }, -10L }; - yield return new object[] { new long[] { 3000, 100, 200, 1000 }, 100L }; - yield return new object[] { new long[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(long.MinValue, 1)), long.MinValue }; + foreach ((long[] array, long expected) in new[] + { + (new[] { 42L }, 42L), + (Enumerable.Range(1, 10).Select(i => (long)i).ToArray(), 1L), + (new long[] { -1, -10, 10, 200, 1000 }, -10L), + (new long[] { 3000, 100, 200, 1000 }, 100L), + (new long[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(long.MinValue, 1)).ToArray(), long.MinValue), + + (new[] { int.MaxValue + 10L }, int.MaxValue + 10L), + (Enumerable.Repeat(500L, 5).ToArray(), 500L), + (new long[] { -250, 49, 130, 47, 28 }, -250L), + (new long[] { 6, 9, 10, 0, -int.MaxValue - 50L }, -int.MaxValue - 50L), + (new long[] { 6, -5, 9, -5, 10, -5 }, -5), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } - yield return new object[] { Enumerable.Repeat(int.MaxValue + 10L, 1), int.MaxValue + 10L }; - yield return new object[] { Enumerable.Repeat(500L, 5), 500L }; - yield return new object[] { new long[] { -250, 49, 130, 47, 28 }, -250L }; - yield return new object[] { new long[] { 6, 9, 10, 0, -int.MaxValue - 50L }, -int.MaxValue - 50L }; - yield return new object[] { new long[] { 6, -5, 9, -5, 10, -5 }, -5 }; + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (long)i)), (long)length }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (long)i).ToArray()), (long)length }; + } } [Theory] @@ -101,43 +129,58 @@ public void Min_Long_EmptySource_ThrowsInvalidOperationException() { Assert.Throws(() => Enumerable.Empty().Min()); Assert.Throws(() => Enumerable.Empty().Min(x => x)); + Assert.Throws(() => Array.Empty().Min()); + Assert.Throws(() => new List().Min()); } public static IEnumerable Min_Float_TestData() { - yield return new object[] { Enumerable.Repeat(42f, 1), 42f }; - yield return new object[] { Enumerable.Range(1, 10).Select(i => (float)i).ToArray(), 1f }; - yield return new object[] { new float[] { -1, -10, 10, 200, 1000 }, -10f }; - yield return new object[] { new float[] { 3000, 100, 200, 1000 }, 100 }; - yield return new object[] { new float[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(float.MinValue, 1)), float.MinValue }; - - yield return new object[] { Enumerable.Repeat(5.5f, 1), 5.5f }; - yield return new object[] { Enumerable.Repeat(float.NaN, 5), float.NaN }; - yield return new object[] { new float[] { -2.5f, 4.9f, 130f, 4.7f, 28f }, -2.5f}; - yield return new object[] { new float[] { 6.8f, 9.4f, 10f, 0, -5.6f }, -5.6f }; - yield return new object[] { new float[] { -5.5f, float.NegativeInfinity, 9.9f, float.NegativeInfinity }, float.NegativeInfinity }; - - yield return new object[] { new float[] { float.NaN, 6.8f, 9.4f, 10f, 0, -5.6f }, float.NaN }; - yield return new object[] { new float[] { 6.8f, 9.4f, 10f, 0, -5.6f, float.NaN }, float.NaN }; - yield return new object[] { new float[] { float.NaN, float.NegativeInfinity }, float.NaN }; - yield return new object[] { new float[] { float.NegativeInfinity, float.NaN }, float.NaN }; + foreach ((float[] array, float expected) in new[] + { + (new[] { 42f }, 42f), + (Enumerable.Range(1, 10).Select(i => (float)i).ToArray(), 1f), + (new float[] { -1, -10, 10, 200, 1000 }, -10f), + (new float[] { 3000, 100, 200, 1000 }, 100), + (new float[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(float.MinValue, 1)).ToArray(), float.MinValue), + + (new[] { 5.5f }, 5.5f), + (Enumerable.Repeat(float.NaN, 5).ToArray(), float.NaN), + (new float[] { -2.5f, 4.9f, 130f, 4.7f, 28f }, -2.5f), + (new float[] { 6.8f, 9.4f, 10f, 0, -5.6f }, -5.6f), + (new float[] { -5.5f, float.NegativeInfinity, 9.9f, float.NegativeInfinity }, float.NegativeInfinity), + + (new float[] { float.NaN, 6.8f, 9.4f, 10f, 0, -5.6f }, float.NaN), + (new float[] { 6.8f, 9.4f, 10f, 0, -5.6f, float.NaN }, float.NaN), + (new float[] { float.NaN, float.NegativeInfinity }, float.NaN), + (new float[] { float.NegativeInfinity, float.NaN }, float.NaN), + + // Normally NaN < anything is false, as is anything < NaN + // However, this leads to some irksome outcomes in Min and Max. + // If we use those semantics then Min(NaN, 5.0) is NaN, but + // Min(5.0, NaN) is 5.0! To fix this, we impose a total + // ordering where NaN is smaller than every value, including + // negative infinity. + (Enumerable.Range(1, 10).Select(i => (float)i).Concat(Enumerable.Repeat(float.NaN, 1)).ToArray(), float.NaN), + (new float[] { -1F, -10, float.NaN, 10, 200, 1000 }, float.NaN), + (new float[] { float.MinValue, 3000F, 100, 200, float.NaN, 1000 }, float.NaN), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } // In .NET Core, Enumerable.Min shortcircuits if it finds any float.NaN in the array, // as nothing can be less than float.NaN. See https://github.com/dotnet/corefx/pull/2426. // Without this optimization, we would iterate through int.MaxValue elements, which takes // a long time. yield return new object[] { Enumerable.Repeat(float.NaN, int.MaxValue), float.NaN }; - yield return new object[] { Enumerable.Repeat(float.NaN, 3), float.NaN }; + yield return new object[] { Enumerable.Repeat(float.NaN, 3).ToArray(), float.NaN }; - // Normally NaN < anything is false, as is anything < NaN - // However, this leads to some irksome outcomes in Min and Max. - // If we use those semantics then Min(NaN, 5.0) is NaN, but - // Min(5.0, NaN) is 5.0! To fix this, we impose a total - // ordering where NaN is smaller than every value, including - // negative infinity. - yield return new object[] { Enumerable.Range(1, 10).Select(i => (float)i).Concat(Enumerable.Repeat(float.NaN, 1)).ToArray(), float.NaN }; - yield return new object[] { new float[] { -1F, -10, float.NaN, 10, 200, 1000 }, float.NaN }; - yield return new object[] { new float[] { float.MinValue, 3000F, 100, 200, float.NaN, 1000 }, float.NaN }; + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (float)i)), (float)length }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (float)i).ToArray()), (float)length }; + } } [Theory] @@ -160,42 +203,56 @@ public void Min_Float_EmptySource_ThrowsInvalidOperationException() { Assert.Throws(() => Enumerable.Empty().Min()); Assert.Throws(() => Enumerable.Empty().Min(x => x)); + Assert.Throws(() => Array.Empty().Min()); + Assert.Throws(() => new List().Min()); } public static IEnumerable Min_Double_TestData() { - yield return new object[] { Enumerable.Repeat(42.0, 1), 42.0 }; - yield return new object[] { Enumerable.Range(1, 10).Select(i => (double)i).ToArray(), 1.0 }; - yield return new object[] { new double[] { -1, -10, 10, 200, 1000 }, -10.0 }; - yield return new object[] { new double[] { 3000, 100, 200, 1000 }, 100.0 }; - yield return new object[] { new double[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(double.MinValue, 1)), double.MinValue }; - - yield return new object[] { Enumerable.Repeat(5.5, 1), 5.5 }; - yield return new object[] { new double[] { -2.5, 4.9, 130, 4.7, 28 }, -2.5 }; - yield return new object[] { new double[] { 6.8, 9.4, 10, 0, -5.6 }, -5.6 }; - yield return new object[] { new double[] { -5.5, double.NegativeInfinity, 9.9, double.NegativeInfinity }, double.NegativeInfinity }; + foreach ((double[] array, double expected) in new[] + { + (new[] { 42.0 }, 42.0), + (Enumerable.Range(1, 10).Select(i => (double)i).ToArray(), 1.0 ), + (new double[] { -1, -10, 10, 200, 1000 }, -10.0), + (new double[] { 3000, 100, 200, 1000 }, 100.0), + (new double[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(double.MinValue, 1)).ToArray(), double.MinValue), + + (new[] { 5.5 }, 5.5), + (new double[] { -2.5, 4.9, 130, 4.7, 28 }, -2.5), + (new double[] { 6.8, 9.4, 10, 0, -5.6 }, -5.6), + (new double[] { -5.5, double.NegativeInfinity, 9.9, double.NegativeInfinity }, double.NegativeInfinity), + + (new double[] { double.NaN, 6.8, 9.4, 10, 0, -5.6 }, double.NaN), + (new double[] { 6.8, 9.4, 10, 0, -5.6, double.NaN }, double.NaN), + (new double[] { double.NaN, double.NegativeInfinity }, double.NaN), + (new double[] { double.NegativeInfinity, double.NaN }, double.NaN), + + // Normally NaN < anything is false, as is anything < NaN + // However, this leads to some irksome outcomes in Min and Max. + // If we use those semantics then Min(NaN, 5.0) is NaN, but + // Min(5.0, NaN) is 5.0! To fix this, we impose a total + // ordering where NaN is smaller than every value, including + // negative infinity. + (Enumerable.Range(1, 10).Select(i => (double)i).Concat(Enumerable.Repeat(double.NaN, 1)).ToArray(), double.NaN), + (new double[] { -1, -10, double.NaN, 10, 200, 1000 }, double.NaN), + (new double[] { double.MinValue, 3000F, 100, 200, double.NaN, 1000 }, double.NaN), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } // In .NET Core, Enumerable.Min shortcircuits if it finds any double.NaN in the array, // as nothing can be less than double.NaN. See https://github.com/dotnet/corefx/pull/2426. // Without this optimization, we would iterate through int.MaxValue elements, which takes // a long time. yield return new object[] { Enumerable.Repeat(double.NaN, int.MaxValue), double.NaN }; - yield return new object[] { Enumerable.Repeat(double.NaN, 3), double.NaN }; - - yield return new object[] { new double[] { double.NaN, 6.8, 9.4, 10, 0, -5.6 }, double.NaN }; - yield return new object[] { new double[] { 6.8, 9.4, 10, 0, -5.6, double.NaN }, double.NaN }; - yield return new object[] { new double[] { double.NaN, double.NegativeInfinity }, double.NaN }; - yield return new object[] { new double[] { double.NegativeInfinity, double.NaN }, double.NaN }; - // Normally NaN < anything is false, as is anything < NaN - // However, this leads to some irksome outcomes in Min and Max. - // If we use those semantics then Min(NaN, 5.0) is NaN, but - // Min(5.0, NaN) is 5.0! To fix this, we impose a total - // ordering where NaN is smaller than every value, including - // negative infinity. - yield return new object[] { Enumerable.Range(1, 10).Select(i => (double)i).Concat(Enumerable.Repeat(double.NaN, 1)).ToArray(), double.NaN }; - yield return new object[] { new double[] { -1, -10, double.NaN, 10, 200, 1000 }, double.NaN }; - yield return new object[] { new double[] { double.MinValue, 3000F, 100, 200, double.NaN, 1000 }, double.NaN }; + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (double)i)), (double)length }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (double)i).ToArray()), (double)length }; + } } [Theory] @@ -218,21 +275,36 @@ public void Min_Double_EmptySource_ThrowsInvalidOperationException() { Assert.Throws(() => Enumerable.Empty().Min()); Assert.Throws(() => Enumerable.Empty().Min(x => x)); + Assert.Throws(() => Array.Empty().Min()); + Assert.Throws(() => new List().Min()); } public static IEnumerable Min_Decimal_TestData() { - yield return new object[] { Enumerable.Repeat(42m, 1), 42m }; - yield return new object[] { Enumerable.Range(1, 10).Select(i => (decimal)i).ToArray(), 1m }; - yield return new object[] { new decimal[] { -1, -10, 10, 200, 1000 }, -10m }; - yield return new object[] { new decimal[] { 3000, 100, 200, 1000 }, 100m }; - yield return new object[] { new decimal[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(decimal.MinValue, 1)), decimal.MinValue }; + foreach ((decimal[] array, decimal expected) in new[] + { + (new[] { 42m }, 42m), + (Enumerable.Range(1, 10).Select(i => (decimal)i).ToArray(), 1m), + (new decimal[] { -1, -10, 10, 200, 1000 }, -10m), + (new decimal[] { 3000, 100, 200, 1000 }, 100m), + (new decimal[] { 3000, 100, 200, 1000 }.Concat(Enumerable.Repeat(decimal.MinValue, 1)).ToArray(), decimal.MinValue), + + (new[] { 5.5m }, 5.5m), + (Enumerable.Repeat(-3.4m, 5).ToArray(), -3.4m), + (new decimal[] { -2.5m, 4.9m, 130m, 4.7m, 28m }, -2.5m), + (new decimal[] { 6.8m, 9.4m, 10m, 0m, 0m, decimal.MinValue }, decimal.MinValue), + (new decimal[] { -5.5m, 0m, 9.9m, -5.5m, 5m }, -5.5m), + }) + { + yield return new object[] { new TestEnumerable(array), expected }; + yield return new object[] { array, expected }; + } - yield return new object[] { Enumerable.Repeat(5.5m, 1), 5.5m }; - yield return new object[] { Enumerable.Repeat(-3.4m, 5), -3.4m }; - yield return new object[] { new decimal[] { -2.5m, 4.9m, 130m, 4.7m, 28m }, -2.5m }; - yield return new object[] { new decimal[] { 6.8m, 9.4m, 10m, 0m, 0m, decimal.MinValue }, decimal.MinValue }; - yield return new object[] { new decimal[] { -5.5m, 0m, 9.9m, -5.5m, 5m }, -5.5m }; + for (int length = 2; length < 33; length++) + { + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (decimal)i)), (decimal)length }; + yield return new object[] { Shuffler.Shuffle(Enumerable.Range(length, length).Select(i => (decimal)i).ToArray()), (decimal)length }; + } } [Theory] @@ -248,6 +320,8 @@ public void Min_Decimal_EmptySource_ThrowsInvalidOperationException() { Assert.Throws(() => Enumerable.Empty().Min()); Assert.Throws(() => Enumerable.Empty().Min(x => x)); + Assert.Throws(() => Array.Empty().Min()); + Assert.Throws(() => new List().Min()); } [Fact] @@ -486,6 +560,8 @@ public void Min_DateTime_EmptySource_ThrowsInvalidOperationException() { Assert.Throws(() => Enumerable.Empty().Min()); Assert.Throws(() => Enumerable.Empty().Min(x => x)); + Assert.Throws(() => Array.Empty().Min()); + Assert.Throws(() => new List().Min()); } public static IEnumerable Min_String_TestData() diff --git a/src/libraries/System.Linq/tests/Shuffler.cs b/src/libraries/System.Linq/tests/Shuffler.cs index dd1dcf3a7459e6..bc64044f42dd7d 100644 --- a/src/libraries/System.Linq/tests/Shuffler.cs +++ b/src/libraries/System.Linq/tests/Shuffler.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections; using System.Collections.Generic; @@ -9,6 +8,18 @@ namespace System.Linq.Tests { public static class Shuffler { + public static T[] Shuffle(T[] array) + { + var r = new Random(42); + int i = array.Length; + while (i > 1) + { + int j = r.Next(i--); + (array[i], array[j]) = (array[j], array[i]); + } + return array; + } + public static IEnumerable Shuffle(this IEnumerable source, int seed) { return new ShuffledEnumerable(source, seed); @@ -37,7 +48,7 @@ public ShuffledEnumerable(IEnumerable source, int seed) public IEnumerator GetEnumerator() { - Random rnd = _seed.HasValue ? new Random(_seed.GetValueOrDefault()) : new Random(); + Random rnd = new Random(_seed.HasValue ? _seed.GetValueOrDefault() : 42); T[] array = _source.ToArray(); int count = array.Length; for (int i = array.Length - 1; i > 0; --i) diff --git a/src/libraries/System.Memory.Data/src/System.Memory.Data.csproj b/src/libraries/System.Memory.Data/src/System.Memory.Data.csproj index fc193b493e4f83..27ac55507950ed 100644 --- a/src/libraries/System.Memory.Data/src/System.Memory.Data.csproj +++ b/src/libraries/System.Memory.Data/src/System.Memory.Data.csproj @@ -1,11 +1,9 @@ - + $(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true enable true - - 1.0.2 A lightweight abstraction for a payload of bytes. Provides methods for converting between strings, streams, JSON, and bytes. Commonly Used Types: diff --git a/src/libraries/System.Memory/System.Memory.sln b/src/libraries/System.Memory/System.Memory.sln index 45e9126c73cb94..a7717e3aca27e5 100644 --- a/src/libraries/System.Memory/System.Memory.sln +++ b/src/libraries/System.Memory/System.Memory.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Memory", "src\System EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Memory.Tests", "tests\System.Memory.Tests.csproj", "{C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{EFF00253-633C-4D2F-86EE-F40C721F6A68}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{EFF00253-633C-4D2F-86EE-F40C721F6A68}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{94F64A00-DB8D-49F1-BB5E-25527DCE9F42}" EndProject diff --git a/src/libraries/System.Net.Http.WinHttpHandler/NuGet.config b/src/libraries/System.Net.Http.WinHttpHandler/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Net.Http.WinHttpHandler/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj index 3ff105557a87bd..bacef00d3e5d03 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.1-windows;netstandard2.1;netstandard2.0-windows;netstandard2.0;$(NetFrameworkMinimum) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum) true enable true diff --git a/src/libraries/System.Net.Http/src/Resources/Strings.resx b/src/libraries/System.Net.Http/src/Resources/Strings.resx index 9e9afe1491426f..d830ac940b61c4 100644 --- a/src/libraries/System.Net.Http/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Http/src/Resources/Strings.resx @@ -591,4 +591,7 @@ The proxy tunnel request to proxy '{0}' failed with status code '{1}'." + + System.Net.Http is not supported on this platform. + diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index 8b5076b5ca9e37..bf7173a54c53ad 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -3,7 +3,7 @@ win true $(DefineConstants);HTTP_DLL - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-MacCatalyst;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris;$(NetCoreAppCurrent)-Android + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-MacCatalyst;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-Solaris;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent) enable @@ -31,21 +31,29 @@ $(MSBuildThisFileDirectory)ILLink\ + + + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) + SR.PlatformNotSupported_NetHttp + - + + + + @@ -128,6 +136,7 @@ + + - + @@ -521,15 +532,6 @@ - - - - - - - - @@ -649,7 +651,6 @@ - @@ -673,8 +674,10 @@ + + @@ -692,7 +695,4 @@ - - - diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs index 8d022091ea3961..b03247fbfc3d7e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/BrowserHttpHandler.cs @@ -148,10 +148,10 @@ protected internal override async Task SendAsync(HttpReques { throw new ArgumentNullException(nameof(request), SR.net_http_handler_norequest); } - + CancellationTokenRegistration? abortRegistration = null; try { - var requestObject = new JSObject(); + using var requestObject = new JSObject(); if (request.Options.TryGetValue(FetchOptions, out IDictionary? fetchOptions)) { @@ -221,44 +221,39 @@ protected internal override async Task SendAsync(HttpReques } - WasmHttpReadStream? wasmHttpReadStream = null; - JSObject abortController = new HostObject("AbortController"); - JSObject signal = (JSObject)abortController.GetObjectProperty("signal"); + using JSObject signal = (JSObject)abortController.GetObjectProperty("signal"); requestObject.SetObjectProperty("signal", signal); - signal.Dispose(); - CancellationTokenSource abortCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - CancellationTokenRegistration abortRegistration = abortCts.Token.Register((Action)(() => + abortRegistration = cancellationToken.Register(() => { - if (abortController.JSHandle != -1) + if (!abortController.IsDisposed) { abortController.Invoke("abort"); abortController?.Dispose(); } - wasmHttpReadStream?.Dispose(); - abortCts.Dispose(); - })); + }); - var args = new System.Runtime.InteropServices.JavaScript.Array(); + using var args = new System.Runtime.InteropServices.JavaScript.Array(); if (request.RequestUri != null) { args.Push(request.RequestUri.ToString()); args.Push(requestObject); } - requestObject.Dispose(); - var response = s_fetch?.Invoke("apply", s_window, args) as Task; - args.Dispose(); - if (response == null) + var responseTask = s_fetch?.Invoke("apply", s_window, args) as Task; + if (responseTask == null) throw new Exception(SR.net_http_marshalling_response_promise_from_fetch); - JSObject t = (JSObject)await response.ConfigureAwait(continueOnCapturedContext: true); + cancellationToken.ThrowIfCancellationRequested(); - var status = new WasmFetchResponse(t, abortController, abortCts, abortRegistration); - HttpResponseMessage httpResponse = new HttpResponseMessage((HttpStatusCode)status.Status); - httpResponse.RequestMessage = request; + var fetchResponseJs = (JSObject)await responseTask.ConfigureAwait(continueOnCapturedContext: true); + + var fetchResponse = new WasmFetchResponse(fetchResponseJs, abortController, abortRegistration.Value); + abortRegistration = null; + var responseMessage = new HttpResponseMessage((HttpStatusCode)fetchResponse.Status); + responseMessage.RequestMessage = request; // Here we will set the ReasonPhrase so that it can be evaluated later. // We do not have a status code but this will signal some type of what happened @@ -267,9 +262,9 @@ protected internal override async Task SendAsync(HttpReques // https://developer.mozilla.org/en-US/docs/Web/API/Response/type // opaqueredirect: The fetch request was made with redirect: "manual". // The Response's status is 0, headers are empty, body is null and trailer is empty. - if (status.ResponseType == "opaqueredirect") + if (fetchResponse.ResponseType == "opaqueredirect") { - httpResponse.SetReasonPhraseWithoutValidation(status.ResponseType); + responseMessage.SetReasonPhraseWithoutValidation(fetchResponse.ResponseType); } bool streamingEnabled = false; @@ -278,9 +273,9 @@ protected internal override async Task SendAsync(HttpReques request.Options.TryGetValue(EnableStreamingResponse, out streamingEnabled); } - httpResponse.Content = streamingEnabled - ? new StreamContent(wasmHttpReadStream = new WasmHttpReadStream(status)) - : (HttpContent)new BrowserHttpContent(status); + responseMessage.Content = streamingEnabled + ? new StreamContent(new WasmHttpReadStream(fetchResponse)) + : new BrowserHttpContent(fetchResponse); // Fill the response headers // CORS will only allow access to certain headers. @@ -290,7 +285,7 @@ protected internal override async Task SendAsync(HttpReques // View more information https://developers.google.com/web/updates/2015/03/introduction-to-fetch#response_types // // Note: Some of the headers may not even be valid header types in .NET thus we use TryAddWithoutValidation - using (JSObject respHeaders = status.Headers) + using (JSObject respHeaders = fetchResponse.Headers) { if (respHeaders != null) { @@ -306,8 +301,8 @@ protected internal override async Task SendAsync(HttpReques { var name = (string)resultValue[0]; var value = (string)resultValue[1]; - if (!httpResponse.Headers.TryAddWithoutValidation(name, value)) - httpResponse.Content.Headers.TryAddWithoutValidation(name, value); + if (!responseMessage.Headers.TryAddWithoutValidation(name, value)) + responseMessage.Content.Headers.TryAddWithoutValidation(name, value); } nextResult?.Dispose(); nextResult = (JSObject)entriesIterator.Invoke("next"); @@ -320,7 +315,7 @@ protected internal override async Task SendAsync(HttpReques } } } - return httpResponse; + return responseMessage; } catch (OperationCanceledException oce) when (cancellationToken.IsCancellationRequested) @@ -331,6 +326,10 @@ protected internal override async Task SendAsync(HttpReques { throw TranslateJSException(jse, cancellationToken); } + finally + { + abortRegistration?.Dispose(); + } } private static Exception TranslateJSException(JSException jse, CancellationToken cancellationToken) @@ -350,15 +349,13 @@ private sealed class WasmFetchResponse : IDisposable { private readonly JSObject _fetchResponse; private readonly JSObject _abortController; - private readonly CancellationTokenSource _abortCts; private readonly CancellationTokenRegistration _abortRegistration; private bool _isDisposed; - public WasmFetchResponse(JSObject fetchResponse, JSObject abortController, CancellationTokenSource abortCts, CancellationTokenRegistration abortRegistration) + public WasmFetchResponse(JSObject fetchResponse, JSObject abortController, CancellationTokenRegistration abortRegistration) { _fetchResponse = fetchResponse ?? throw new ArgumentNullException(nameof(fetchResponse)); _abortController = abortController ?? throw new ArgumentNullException(nameof(abortController)); - _abortCts = abortCts; _abortRegistration = abortRegistration; } @@ -383,10 +380,13 @@ public void Dispose() _isDisposed = true; - _abortCts.Dispose(); _abortRegistration.Dispose(); _fetchResponse?.Dispose(); + if (_abortController != null && !_abortController.IsDisposed) + { + _abortController.Invoke("abort"); + } _abortController?.Dispose(); } } @@ -460,15 +460,15 @@ protected override void Dispose(bool disposing) private sealed class WasmHttpReadStream : Stream { - private WasmFetchResponse? _status; + private WasmFetchResponse? _fetchResponse; private JSObject? _reader; private byte[]? _bufferedBytes; private int _position; - public WasmHttpReadStream(WasmFetchResponse status) + public WasmHttpReadStream(WasmFetchResponse fetchResponse) { - _status = status; + _fetchResponse = fetchResponse; } public override bool CanRead => true; @@ -489,17 +489,19 @@ public override Task ReadAsync(byte[] buffer, int offset, int count, Cancel public override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken) { + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + if (_reader == null) { // If we've read everything, then _reader and _status will be null - if (_status == null) + if (_fetchResponse == null) { return 0; } try { - using (JSObject body = _status.Body) + using (JSObject body = _fetchResponse.Body) { _reader = (JSObject)body.Invoke("getReader"); } @@ -514,6 +516,11 @@ public override async ValueTask ReadAsync(Memory buffer, Cancellation } } + using var abortRegistration = cancellationToken.Register(() => + { + _reader.Invoke("cancel"); + }); + if (_bufferedBytes != null && _position < _bufferedBytes.Length) { return ReadBuffered(); @@ -524,13 +531,19 @@ public override async ValueTask ReadAsync(Memory buffer, Cancellation var t = (Task)_reader.Invoke("read"); using (var read = (JSObject)await t.ConfigureAwait(continueOnCapturedContext: true)) { + if (cancellationToken.IsCancellationRequested) + { + _reader.Invoke("cancel"); + throw CancellationHelper.CreateOperationCanceledException(null, cancellationToken); + } + if ((bool)read.GetObjectProperty("done")) { _reader.Dispose(); _reader = null; - _status?.Dispose(); - _status = null; + _fetchResponse?.Dispose(); + _fetchResponse = null; return 0; } @@ -569,7 +582,7 @@ int ReadBuffered() protected override void Dispose(bool disposing) { _reader?.Dispose(); - _status?.Dispose(); + _fetchResponse?.Dispose(); } public override void Flush() diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs index 229490b5432dd9..d04c9f4877e48e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs @@ -15,32 +15,44 @@ namespace System.Net.Http.Headers // Use HeaderDescriptor.TryGet to resolve an arbitrary header name to a HeaderDescriptor. internal readonly struct HeaderDescriptor : IEquatable { - private readonly string _headerName; - private readonly KnownHeader? _knownHeader; + /// + /// Either a or . + /// + private readonly object _descriptor; public HeaderDescriptor(KnownHeader knownHeader) { - _knownHeader = knownHeader; - _headerName = knownHeader.Name; + _descriptor = knownHeader; } // This should not be used directly; use static TryGet below - internal HeaderDescriptor(string headerName) + internal HeaderDescriptor(string headerName, bool customHeader = false) { - _headerName = headerName; - _knownHeader = null; + Debug.Assert(customHeader || KnownHeaders.TryGetKnownHeader(headerName) is null, $"The {nameof(KnownHeader)} overload should be used for {headerName}"); + _descriptor = headerName; } - public string Name => _headerName; - public HttpHeaderParser? Parser => _knownHeader?.Parser; - public HttpHeaderType HeaderType => _knownHeader == null ? HttpHeaderType.Custom : _knownHeader.HeaderType; - public KnownHeader? KnownHeader => _knownHeader; + public string Name => _descriptor is KnownHeader header ? header.Name : (_descriptor as string)!; + public HttpHeaderParser? Parser => (_descriptor as KnownHeader)?.Parser; + public HttpHeaderType HeaderType => _descriptor is KnownHeader knownHeader ? knownHeader.HeaderType : HttpHeaderType.Custom; + public KnownHeader? KnownHeader => _descriptor as KnownHeader; + + public bool Equals(KnownHeader other) => ReferenceEquals(_descriptor, other); + + public bool Equals(HeaderDescriptor other) + { + if (_descriptor is string headerName) + { + return string.Equals(headerName, other._descriptor as string, StringComparison.OrdinalIgnoreCase); + } + else + { + return ReferenceEquals(_descriptor, other._descriptor); + } + } + + public override int GetHashCode() => _descriptor is KnownHeader knownHeader ? knownHeader.GetHashCode() : StringComparer.OrdinalIgnoreCase.GetHashCode(_descriptor); - public bool Equals(HeaderDescriptor other) => - _knownHeader == null ? - string.Equals(_headerName, other._headerName, StringComparison.OrdinalIgnoreCase) : - _knownHeader == other._knownHeader; - public override int GetHashCode() => _knownHeader?.GetHashCode() ?? StringComparer.OrdinalIgnoreCase.GetHashCode(_headerName); public override bool Equals(object? obj) => throw new InvalidOperationException(); // Ensure this is never called, to avoid boxing // Returns false for invalid header name. @@ -112,9 +124,9 @@ internal static bool TryGetStaticQPackHeader(int index, out HeaderDescriptor des public HeaderDescriptor AsCustomHeader() { - Debug.Assert(_knownHeader != null); - Debug.Assert(_knownHeader.HeaderType != HttpHeaderType.Custom); - return new HeaderDescriptor(_knownHeader.Name); + Debug.Assert(_descriptor is KnownHeader); + Debug.Assert(HeaderType != HttpHeaderType.Custom); + return new HeaderDescriptor(Name, customHeader: true); } public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEncoding) @@ -125,21 +137,20 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco } // If it's a known header value, use the known value instead of allocating a new string. - if (_knownHeader != null) + if (_descriptor is KnownHeader knownHeader) { - string[]? knownValues = _knownHeader.KnownValues; - if (knownValues != null) + if (knownHeader.KnownValues is string[] knownValues) { for (int i = 0; i < knownValues.Length; i++) { - if (ByteArrayHelpers.EqualsOrdinalAsciiIgnoreCase(knownValues[i], headerValue)) + if (ByteArrayHelpers.EqualsOrdinalAscii(knownValues[i], headerValue)) { return knownValues[i]; } } } - if (_knownHeader == KnownHeaders.ContentType) + if (knownHeader == KnownHeaders.ContentType) { string? contentType = GetKnownContentType(headerValue); if (contentType != null) @@ -147,7 +158,7 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco return contentType; } } - else if (_knownHeader == KnownHeaders.Location) + else if (knownHeader == KnownHeaders.Location) { // Normally Location should be in ISO-8859-1 but occasionally some servers respond with UTF-8. if (TryDecodeUtf8(headerValue, out string? decoded)) @@ -166,45 +177,45 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco switch (contentTypeValue.Length) { case 8: - switch (contentTypeValue[7] | 0x20) + switch (contentTypeValue[7]) { - case 'l': candidate = "text/xml"; break; // text/xm[l] - case 's': candidate = "text/css"; break; // text/cs[s] - case 'v': candidate = "text/csv"; break; // text/cs[v] + case (byte)'l': candidate = "text/xml"; break; // text/xm[l] + case (byte)'s': candidate = "text/css"; break; // text/cs[s] + case (byte)'v': candidate = "text/csv"; break; // text/cs[v] } break; case 9: - switch (contentTypeValue[6] | 0x20) + switch (contentTypeValue[6]) { - case 'g': candidate = "image/gif"; break; // image/[g]if - case 'p': candidate = "image/png"; break; // image/[p]ng - case 't': candidate = "text/html"; break; // text/h[t]ml + case (byte)'g': candidate = "image/gif"; break; // image/[g]if + case (byte)'p': candidate = "image/png"; break; // image/[p]ng + case (byte)'t': candidate = "text/html"; break; // text/h[t]ml } break; case 10: - switch (contentTypeValue[0] | 0x20) + switch (contentTypeValue[0]) { - case 't': candidate = "text/plain"; break; // [t]ext/plain - case 'i': candidate = "image/jpeg"; break; // [i]mage/jpeg + case (byte)'t': candidate = "text/plain"; break; // [t]ext/plain + case (byte)'i': candidate = "image/jpeg"; break; // [i]mage/jpeg } break; case 15: - switch (contentTypeValue[12] | 0x20) + switch (contentTypeValue[12]) { - case 'p': candidate = "application/pdf"; break; // application/[p]df - case 'x': candidate = "application/xml"; break; // application/[x]ml - case 'z': candidate = "application/zip"; break; // application/[z]ip + case (byte)'p': candidate = "application/pdf"; break; // application/[p]df + case (byte)'x': candidate = "application/xml"; break; // application/[x]ml + case (byte)'z': candidate = "application/zip"; break; // application/[z]ip } break; case 16: - switch (contentTypeValue[12] | 0x20) + switch (contentTypeValue[12]) { - case 'g': candidate = "application/grpc"; break; // application/[g]rpc - case 'j': candidate = "application/json"; break; // application/[j]son + case (byte)'g': candidate = "application/grpc"; break; // application/[g]rpc + case (byte)'j': candidate = "application/json"; break; // application/[j]son } break; @@ -217,10 +228,11 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco break; case 24: - switch (contentTypeValue[0] | 0x20) + switch (contentTypeValue[19]) { - case 'a': candidate = "application/octet-stream"; break; // application/octet-stream - case 't': candidate = "text/html; charset=utf-8"; break; // text/html; charset=utf-8 + case (byte)'t': candidate = "application/octet-stream"; break; // application/octet-s[t]ream + case (byte)'u': candidate = "text/html; charset=utf-8"; break; // text/html; charset=[u]tf-8 + case (byte)'U': candidate = "text/html; charset=UTF-8"; break; // text/html; charset=[U]TF-8 } break; @@ -239,7 +251,7 @@ public string GetHeaderValue(ReadOnlySpan headerValue, Encoding? valueEnco Debug.Assert(candidate is null || candidate.Length == contentTypeValue.Length); - return candidate != null && ByteArrayHelpers.EqualsOrdinalAsciiIgnoreCase(candidate, contentTypeValue) ? + return candidate != null && ByteArrayHelpers.EqualsOrdinalAscii(candidate, contentTypeValue) ? candidate : null; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs index 3eae142edcd4cb..266d471001835b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs @@ -772,7 +772,7 @@ private static void ParseMultipleRawHeaderValues(HeaderDescriptor descriptor, He { foreach (string rawValue in rawValues) { - if (!ContainsNewLine(rawValue, descriptor.Name)) + if (!ContainsNewLine(rawValue, descriptor)) { AddParsedValue(info, rawValue); } @@ -797,7 +797,7 @@ private static void ParseSingleRawHeaderValue(HeaderDescriptor descriptor, Heade if (descriptor.Parser == null) { - if (!ContainsNewLine(rawValue, descriptor.Name)) + if (!ContainsNewLine(rawValue, descriptor)) { AddParsedValue(info, rawValue); } @@ -887,7 +887,7 @@ private static bool TryParseAndAddRawHeaderValue(HeaderDescriptor descriptor, He } else { - if (!ContainsNewLine(value, descriptor.Name) && addWhenInvalid) + if (!ContainsNewLine(value, descriptor) && addWhenInvalid) { AddInvalidValue(info, value); } @@ -904,7 +904,7 @@ private static bool TryParseAndAddRawHeaderValue(HeaderDescriptor descriptor, He } Debug.Assert(value != null); - if (!ContainsNewLine(value, descriptor.Name) && addWhenInvalid) + if (!ContainsNewLine(value, descriptor) && addWhenInvalid) { AddInvalidValue(info, value ?? string.Empty); } @@ -1111,11 +1111,11 @@ internal static void CheckContainsNewLine(string? value) } } - private static bool ContainsNewLine(string value, string name) + private static bool ContainsNewLine(string value, HeaderDescriptor descriptor) { if (HttpRuleParser.ContainsNewLine(value)) { - if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(null, SR.Format(SR.net_http_log_headers_no_newlines, name, value)); + if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(null, SR.Format(SR.net_http_log_headers_no_newlines, descriptor.Name, value)); return true; } return false; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/QPackStaticTable.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/QPackStaticTable.cs index bc3d1992146962..e6664bdbf3b6a3 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/QPackStaticTable.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/QPackStaticTable.cs @@ -71,7 +71,7 @@ internal static class QPackStaticTable (new HeaderDescriptor(KnownHeaders.Vary), "accept-encoding"), // 59 (new HeaderDescriptor(KnownHeaders.Vary), "origin"), // 60 (new HeaderDescriptor(KnownHeaders.XContentTypeOptions), "nosniff"), // 61 - (new HeaderDescriptor("x-xss-protection"), "1; mode=block"), // 62 + (new HeaderDescriptor(KnownHeaders.XXssProtection), "1; mode=block"), // 62 (new HeaderDescriptor(KnownHeaders.PseudoStatus), "100"), // 63 (new HeaderDescriptor(KnownHeaders.PseudoStatus), "204"), // 64 (new HeaderDescriptor(KnownHeaders.PseudoStatus), "206"), // 65 @@ -96,7 +96,7 @@ internal static class QPackStaticTable (new HeaderDescriptor(KnownHeaders.Authorization), ""), // 84 (new HeaderDescriptor(KnownHeaders.ContentSecurityPolicy), "script-src 'none'; object-src 'none'; base-uri 'none'"), // 85 (new HeaderDescriptor("early-data"), "1"), // 86 - (new HeaderDescriptor("expect-ct"), ""), // 87 + (new HeaderDescriptor(KnownHeaders.ExpectCT), ""), // 87 (new HeaderDescriptor("forwarded"), ""), // 88 (new HeaderDescriptor(KnownHeaders.IfRange), ""), // 89 (new HeaderDescriptor(KnownHeaders.Origin), ""), // 90 diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.Digest.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.Digest.cs index c754dff03e59dc..e2292112ba7a7a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.Digest.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.Digest.cs @@ -227,17 +227,25 @@ private static string GetRandomAlphaNumericString() private static string ComputeHash(string data, string algorithm) { - // Disable MD5 insecure warning. + Span hashBuffer = stackalloc byte[SHA256.HashSizeInBytes]; // SHA256 is the largest hash produced + byte[] dataBytes = Encoding.UTF8.GetBytes(data); + int written; + + if (algorithm.StartsWith(Sha256, StringComparison.OrdinalIgnoreCase)) + { + written = SHA256.HashData(dataBytes, hashBuffer); + Debug.Assert(written == SHA256.HashSizeInBytes); + } + else + { + // Disable MD5 insecure warning. #pragma warning disable CA5351 - using (HashAlgorithm hash = algorithm.StartsWith(Sha256, StringComparison.OrdinalIgnoreCase) ? SHA256.Create() : (HashAlgorithm)MD5.Create()) + written = MD5.HashData(dataBytes, hashBuffer); + Debug.Assert(written == MD5.HashSizeInBytes); #pragma warning restore CA5351 - { - Span result = stackalloc byte[hash.HashSize / 8]; // HashSize is in bits - bool hashComputed = hash.TryComputeHash(Encoding.UTF8.GetBytes(data), result, out int bytesWritten); - Debug.Assert(hashComputed && bytesWritten == result.Length); - - return HexConverter.ToString(result, HexConverter.Casing.Lower); } + + return HexConverter.ToString(hashBuffer.Slice(0, written), HexConverter.Casing.Lower); } internal sealed class DigestResponse diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index 1a1b4b00bbb60f..a4e224bd5b9b35 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -2038,7 +2038,7 @@ private void VerifyKeepAlive() _keepAlivePingTimeoutTimestamp = now + _keepAlivePingTimeout; long pingPayload = Interlocked.Increment(ref _keepAlivePingPayload); - SendPingAsync(pingPayload); + LogExceptions(SendPingAsync(pingPayload)); return; } break; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs index 9a7ebccc416a8e..6e3c0f17fe40ac 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs @@ -900,7 +900,7 @@ private void OnHeader(int? staticIndex, HeaderDescriptor descriptor, string? sta { if (descriptor.Name[0] == ':') { - if (descriptor.KnownHeader != KnownHeaders.PseudoStatus) + if (!descriptor.Equals(KnownHeaders.PseudoStatus)) { if (NetEventSource.Log.IsEnabled()) Trace($"Received unknown pseudo-header '{descriptor.Name}'."); throw new Http3ConnectionException(Http3ErrorCode.ProtocolError); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs index deb0f5d9373d19..655e57ad8be19a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs @@ -264,9 +264,9 @@ private async ValueTask WriteHeadersAsync(HttpHeaders headers, string? cookiesFr { HeaderEntry header = entries[i]; - if (header.Key.KnownHeader != null) + if (header.Key.KnownHeader is KnownHeader knownHeader) { - await WriteBytesAsync(header.Key.KnownHeader.AsciiBytesWithColonSpace, async).ConfigureAwait(false); + await WriteBytesAsync(knownHeader.AsciiBytesWithColonSpace, async).ConfigureAwait(false); } else { @@ -282,7 +282,7 @@ private async ValueTask WriteHeadersAsync(HttpHeaders headers, string? cookiesFr await WriteStringAsync(_headerValues[0], async, valueEncoding).ConfigureAwait(false); - if (cookiesFromContainer != null && header.Key.KnownHeader == KnownHeaders.Cookie) + if (cookiesFromContainer != null && header.Key.Equals(KnownHeaders.Cookie)) { await WriteTwoBytesAsync((byte)';', (byte)' ', async).ConfigureAwait(false); await WriteStringAsync(cookiesFromContainer, async, valueEncoding).ConfigureAwait(false); @@ -1056,7 +1056,7 @@ private static void ParseHeaderNameValue(HttpConnection connection, ReadOnlySpan throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(line.Slice(0, pos)))); } - if (isFromTrailer && descriptor.KnownHeader != null && (descriptor.KnownHeader.HeaderType & HttpHeaderType.NonTrailing) == HttpHeaderType.NonTrailing) + if (isFromTrailer && (descriptor.HeaderType & HttpHeaderType.NonTrailing) == HttpHeaderType.NonTrailing) { // Disallowed trailer fields. // A recipient MUST ignore fields that are forbidden to be sent in a trailer. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs index 3c266f20da59f5..45eae0fa57649f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs @@ -24,8 +24,8 @@ internal abstract class HttpConnectionBase : IDisposable, IHttpTrace public string GetResponseHeaderValueWithCaching(HeaderDescriptor descriptor, ReadOnlySpan value, Encoding? valueEncoding) { return - ReferenceEquals(descriptor.KnownHeader, KnownHeaders.Date) ? GetOrAddCachedValue(ref _lastDateHeaderValue, descriptor, value, valueEncoding) : - ReferenceEquals(descriptor.KnownHeader, KnownHeaders.Server) ? GetOrAddCachedValue(ref _lastServerHeaderValue, descriptor, value, valueEncoding) : + descriptor.Equals(KnownHeaders.Date) ? GetOrAddCachedValue(ref _lastDateHeaderValue, descriptor, value, valueEncoding) : + descriptor.Equals(KnownHeaders.Server) ? GetOrAddCachedValue(ref _lastServerHeaderValue, descriptor, value, valueEncoding) : descriptor.GetHeaderValue(value, valueEncoding); static string GetOrAddCachedValue([NotNull] ref string? cache, HeaderDescriptor descriptor, ReadOnlySpan value, Encoding? encoding) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 8431f2565e8195..523c25c83bed99 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -1044,12 +1044,12 @@ public sealed class SocketsHttpHandlerTest_Cookies_Http11 : HttpClientHandlerTes public SocketsHttpHandlerTest_Cookies_Http11(ITestOutputHelper output) : base(output) { } } - [SkipOnPlatform(TestPlatforms.Browser, "ConnectTimeout is not supported on Browser")] public sealed class SocketsHttpHandler_HttpClientHandler_Http11_Cancellation_Test : SocketsHttpHandler_Cancellation_Test { public SocketsHttpHandler_HttpClientHandler_Http11_Cancellation_Test(ITestOutputHelper output) : base(output) { } [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "ConnectTimeout is not supported on Browser")] public void ConnectTimeout_Default() { using (var handler = new SocketsHttpHandler()) @@ -1062,6 +1062,7 @@ public void ConnectTimeout_Default() [InlineData(0)] [InlineData(-2)] [InlineData(int.MaxValue + 1L)] + [SkipOnPlatform(TestPlatforms.Browser, "ConnectTimeout is not supported on Browser")] public void ConnectTimeout_InvalidValues(long ms) { using (var handler = new SocketsHttpHandler()) @@ -1075,6 +1076,7 @@ public void ConnectTimeout_InvalidValues(long ms) [InlineData(1)] [InlineData(int.MaxValue - 1)] [InlineData(int.MaxValue)] + [SkipOnPlatform(TestPlatforms.Browser, "ConnectTimeout is not supported on Browser")] public void ConnectTimeout_ValidValues_Roundtrip(long ms) { using (var handler = new SocketsHttpHandler()) @@ -1085,6 +1087,7 @@ public void ConnectTimeout_ValidValues_Roundtrip(long ms) } [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "ConnectTimeout is not supported on Browser")] public void ConnectTimeout_SetAfterUse_Throws() { using (var handler = new SocketsHttpHandler()) @@ -1098,6 +1101,7 @@ public void ConnectTimeout_SetAfterUse_Throws() } [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "ConnectTimeout is not supported on Browser")] public void Expect100ContinueTimeout_Default() { using (var handler = new SocketsHttpHandler()) @@ -1109,6 +1113,7 @@ public void Expect100ContinueTimeout_Default() [Theory] [InlineData(-2)] [InlineData(int.MaxValue + 1L)] + [SkipOnPlatform(TestPlatforms.Browser, "ConnectTimeout is not supported on Browser")] public void Expect100ContinueTimeout_InvalidValues(long ms) { using (var handler = new SocketsHttpHandler()) @@ -1122,6 +1127,7 @@ public void Expect100ContinueTimeout_InvalidValues(long ms) [InlineData(1)] [InlineData(int.MaxValue - 1)] [InlineData(int.MaxValue)] + [SkipOnPlatform(TestPlatforms.Browser, "ConnectTimeout is not supported on Browser")] public void Expect100ContinueTimeout_ValidValues_Roundtrip(long ms) { using (var handler = new SocketsHttpHandler()) @@ -1132,6 +1138,7 @@ public void Expect100ContinueTimeout_ValidValues_Roundtrip(long ms) } [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "ConnectTimeout is not supported on Browser")] public void Expect100ContinueTimeout_SetAfterUse_Throws() { using (var handler = new SocketsHttpHandler()) diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs index 78fada7218b4ac..aac0f0fec5d1c3 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/KnownHeadersTest.cs @@ -177,6 +177,7 @@ public void TryGetKnownHeader_Unknown_NotFound(string name) [InlineData("Content-Type", "application/javascript")] [InlineData("Content-Type", "application/octet-stream")] [InlineData("Content-Type", "text/html; charset=utf-8")] + [InlineData("Content-Type", "text/html; charset=UTF-8")] [InlineData("Content-Type", "text/plain; charset=utf-8")] [InlineData("Content-Type", "application/json; charset=utf-8")] [InlineData("Content-Type", "application/x-www-form-urlencoded")] @@ -213,27 +214,46 @@ public void TryGetKnownHeader_Unknown_NotFound(string name) [InlineData("X-XSS-Protection", "1; mode=block")] public void GetKnownHeaderValue_Known_Found(string name, string value) { - foreach (string casedValue in new[] { value, value.ToUpperInvariant(), value.ToLowerInvariant() }) + KnownHeader knownHeader = KnownHeaders.TryGetKnownHeader(name); + Assert.NotNull(knownHeader); + + string v1 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null); + Assert.NotNull(v1); + Assert.Equal(value, v1); + + string v2 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null); + Assert.Same(v1, v2); + + if (TryChangeCasing(value, out string newValue)) // Doesn't make sense for values that are just numbers { - Validate(KnownHeaders.TryGetKnownHeader(name), casedValue); + GetKnownHeaderValue_Unknown_NotFound(name, newValue); } - static void Validate(KnownHeader knownHeader, string value) + static bool TryChangeCasing(string value, out string newValue) { - Assert.NotNull(knownHeader); + string upper = value.ToUpperInvariant(); + if (upper != value) + { + newValue = upper; + return true; + } - string v1 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null); - Assert.NotNull(v1); - Assert.Equal(value, v1, StringComparer.OrdinalIgnoreCase); + string lower = value.ToLowerInvariant(); + if (lower != value) + { + newValue = lower; + return true; + } - string v2 = knownHeader.Descriptor.GetHeaderValue(value.Select(c => (byte)c).ToArray(), valueEncoding: null); - Assert.Same(v1, v2); + newValue = null; + return false; } } [Theory] [InlineData("Content-Type", "application/jsot")] [InlineData("Content-Type", "application/jsons")] + [InlineData("Transfer-Encoding", "foo")] public void GetKnownHeaderValue_Unknown_NotFound(string name, string value) { KnownHeader knownHeader = KnownHeaders.TryGetKnownHeader(name); diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerPrefixCollectionTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerPrefixCollectionTests.cs index b1f7d3eaa64dec..6b7568084952db 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerPrefixCollectionTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerPrefixCollectionTests.cs @@ -359,6 +359,7 @@ public static IEnumerable InvalidPrefix_TestData() [Theory] [MemberData(nameof(InvalidPrefix_TestData))] + [SkipOnPlatform(TestPlatforms.FreeBSD, "FreeBSD accepts some inputs as valid and test hangs")] public void Add_InvalidPrefixNotStarted_ThrowsHttpListenerExceptionOnStart(string uriPrefix) { var listener = new HttpListener(); @@ -371,6 +372,7 @@ public void Add_InvalidPrefixNotStarted_ThrowsHttpListenerExceptionOnStart(strin [Theory] [MemberData(nameof(InvalidPrefix_TestData))] + [SkipOnPlatform(TestPlatforms.FreeBSD, "FreeBSD accepts some inputs as valid and test hangs")] public void Add_InvalidPrefixAlreadyStarted_ThrowsHttpListenerExceptionOnAdd(string uriPrefix) { using (var factory = new HttpListenerFactory()) diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs index dce9cf7010697e..4309b23ad94e61 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.cs @@ -436,6 +436,7 @@ public async Task CloseResponseEntity_SendToClosedConnection_DoesNotThrow(bool w } [Fact] + [SkipOnPlatform(TestPlatforms.FreeBSD, "unreliable on FreeBSD")] public async Task AddLongHeader_DoesNotThrow() { string longString = new string('a', 65536); diff --git a/src/libraries/System.Net.HttpListener/tests/HttpResponseStreamTests.cs b/src/libraries/System.Net.HttpListener/tests/HttpResponseStreamTests.cs index 4170efafa4ce7e..841fae8c293ca2 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpResponseStreamTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpResponseStreamTests.cs @@ -498,7 +498,7 @@ public async Task Write_ContentToClosedConnectionAsynchronously_ThrowsHttpListen [InlineData(true)] [InlineData(false)] [ActiveIssue("https://github.com/dotnet/runtime/issues/21022", platforms: TestPlatforms.Windows)] // Indeterminate failure - socket not always fully disconnected. - [ActiveIssue("https://github.com/dotnet/runtime/issues/21590", TestPlatforms.OSX)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/21590", TestPlatforms.OSX | TestPlatforms.FreeBSD)] public async Task Write_ContentToClosedConnectionSynchronously_ThrowsHttpListenerException(bool ignoreWriteExceptions) { const string Text = "Some-String"; diff --git a/src/libraries/System.Net.Mail/src/Resources/Strings.resx b/src/libraries/System.Net.Mail/src/Resources/Strings.resx index 06521daf4ca9d5..8f077a3789f67e 100644 --- a/src/libraries/System.Net.Mail/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Mail/src/Resources/Strings.resx @@ -328,4 +328,7 @@ IIS delivery is not supported. + + System.Net.Mail is not supported on this platform. + diff --git a/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj b/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj index 0fa2b097425130..e47a78d8cadefa 100644 --- a/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj +++ b/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj @@ -1,12 +1,16 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-tvOS + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent) enable $(DefineConstants);NO_NTAUTHENTICATION - + + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) + SR.PlatformNotSupported_NetMail + + @@ -77,7 +81,7 @@ - + @@ -115,7 +119,7 @@ - + - @@ -272,7 +275,8 @@ - + + diff --git a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj index 743f3750a6d8b9..250bc924fbd894 100644 --- a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj +++ b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj @@ -1,14 +1,16 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) enable + - SR.SystemNetNameResolution_PlatformNotSupported + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) + SR.SystemNetNameResolution_PlatformNotSupported ExcludeApiList.PNSE.Browser.txt - + @@ -111,7 +113,6 @@ - @@ -123,6 +124,7 @@ + diff --git a/src/libraries/System.Net.Ping/src/Resources/Strings.resx b/src/libraries/System.Net.Ping/src/Resources/Strings.resx index 1a1c7112b5d30d..a2a8a43068beb6 100644 --- a/src/libraries/System.Net.Ping/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Ping/src/Resources/Strings.resx @@ -87,4 +87,7 @@ System.Net.Ping is not supported on this platform. - \ No newline at end of file + + Unable to send custom ping payload. Run program under privileged user account or grant cap_net_raw capability using setcap(8). + + diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.PingUtility.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.PingUtility.cs index 74e85ca493a24e..dc9f5d2124633e 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.PingUtility.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.PingUtility.cs @@ -24,6 +24,14 @@ private Process GetPingProcess(IPAddress address, byte[] buffer, int timeout, Pi throw new PlatformNotSupportedException(SR.net_ping_utility_not_found); } + // although the ping utility supports custom pattern via -p option, it supports + // specifying only up to 16B pattern which repeats in the payload. The option also might + // not be present in all distributions, so we forbid ping payload in general. + if (buffer != DefaultSendBuffer && buffer != Array.Empty()) + { + throw new PlatformNotSupportedException(SR.net_ping_utility_custom_payload); + } + UnixCommandLinePing.PingFragmentOptions fragmentOption = UnixCommandLinePing.PingFragmentOptions.Default; if (options != null && address.AddressFamily == AddressFamily.InterNetwork) { diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs index fcb658a462c2c7..51bde54c68e3a1 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs @@ -227,7 +227,7 @@ public PingReply Send(IPAddress address, int timeout, byte[] buffer, PingOptions { return SendPingCore(addressSnapshot, buffer, timeout, options); } - catch (Exception e) + catch (Exception e) when (e is not PlatformNotSupportedException) { throw new PingException(SR.net_ping, e); } @@ -336,7 +336,7 @@ private async Task SendPingAsyncInternal(IPAddress address, int timeo Task pingReplyTask = SendPingAsyncCore(addressSnapshot, buffer, timeout, options); return await pingReplyTask.ConfigureAwait(false); } - catch (Exception e) + catch (Exception e) when (e is not PlatformNotSupportedException) { throw new PingException(SR.net_ping, e); } @@ -388,7 +388,7 @@ private PingReply GetAddressAndSend(string hostNameOrAddress, int timeout, byte[ IPAddress[] addresses = Dns.GetHostAddresses(hostNameOrAddress); return SendPingCore(addresses[0], buffer, timeout, options); } - catch (Exception e) + catch (Exception e) when (e is not PlatformNotSupportedException) { throw new PingException(SR.net_ping, e); } @@ -407,7 +407,7 @@ private async Task GetAddressAndSendAsync(string hostNameOrAddress, i Task pingReplyTask = SendPingAsyncCore(addresses[0], buffer, timeout, options); return await pingReplyTask.ConfigureAwait(false); } - catch (Exception e) + catch (Exception e) when (e is not PlatformNotSupportedException) { throw new PingException(SR.net_ping, e); } diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index ebd7d44bb49438..57a0a33c44609a 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -6,8 +6,6 @@ using System.Linq; using System.Net.Sockets; using System.Net.Test.Common; -using System.Runtime.InteropServices; -using System.Threading; using System.Threading.Tasks; using Microsoft.DotNet.RemoteExecutor; @@ -74,6 +72,16 @@ private static void PingResultValidator(PingReply pingReply, IPAddress[] localIp Assert.Contains(pingReply.Address, localIpAddresses); ///, "Reply address {pingReply.Address} is not expected local address."); } + private static byte[] GetPingPayload(AddressFamily addressFamily) + // On Unix, Non-root processes cannot send arbitrary data in the ping packet payload + => Capability.CanUseRawSockets(addressFamily) || PlatformDetection.IsOSXLike + ? TestSettings.PayloadAsBytes + : Array.Empty(); + + public static bool DoesNotUsePingUtility => !UsesPingUtility; + + public static bool UsesPingUtility => OperatingSystem.IsLinux() && !Capability.CanUseRawSockets(TestSettings.GetLocalIPAddress().AddressFamily); + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsync_InvalidArgs() { @@ -220,12 +228,11 @@ await SendBatchPingAsync( }); } - [PlatformSpecific(TestPlatforms.Windows)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. [Fact] public void SendPingWithIPAddressAndTimeoutAndBuffer() { - byte[] buffer = TestSettings.PayloadAsBytes; IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); SendBatchPing( (ping) => ping.Send(localIpAddress, TestSettings.PingTimeout, buffer), @@ -236,12 +243,11 @@ public void SendPingWithIPAddressAndTimeoutAndBuffer() }); } - [PlatformSpecific(TestPlatforms.Windows)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithIPAddressAndTimeoutAndBuffer() { - byte[] buffer = TestSettings.PayloadAsBytes; IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); await SendBatchPingAsync( (ping) => ping.SendPingAsync(localIpAddress, TestSettings.PingTimeout, buffer), @@ -252,57 +258,7 @@ await SendBatchPingAsync( }); } - [PlatformSpecific(TestPlatforms.AnyUnix)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - [Fact] - public void SendPingWithIPAddressAndTimeoutAndBuffer_Unix() - { - byte[] buffer = TestSettings.PayloadAsBytes; - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); - - SendBatchPing( - (ping) => ping.Send(localIpAddress, TestSettings.PingTimeout, buffer), - (pingReply) => - { - PingResultValidator(pingReply, localIpAddress); - - // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - if (Capability.CanUseRawSockets(localIpAddress.AddressFamily) || PlatformDetection.IsOSXLike) - { - Assert.Equal(buffer, pingReply.Buffer); - } - else - { - Assert.Equal(Array.Empty(), pingReply.Buffer); - } - }); - } - - [PlatformSpecific(TestPlatforms.AnyUnix)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsyncWithIPAddressAndTimeoutAndBuffer_Unix() - { - byte[] buffer = TestSettings.PayloadAsBytes; - IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); - - await SendBatchPingAsync( - (ping) => ping.SendPingAsync(localIpAddress, TestSettings.PingTimeout, buffer), - (pingReply) => - { - PingResultValidator(pingReply, localIpAddress); - - // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - if (Capability.CanUseRawSockets(localIpAddress.AddressFamily) || PlatformDetection.IsOSXLike) - { - Assert.Equal(buffer, pingReply.Buffer); - } - else - { - Assert.Equal(Array.Empty(), pingReply.Buffer); - } - }); - } - - [PlatformSpecific(TestPlatforms.Windows)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. + [PlatformSpecific(TestPlatforms.Windows)] [Fact] public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions() { @@ -320,7 +276,7 @@ public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions() }); } - [PlatformSpecific(TestPlatforms.Windows)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. + [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions() { @@ -338,7 +294,7 @@ await SendBatchPingAsync( }); } - [PlatformSpecific(TestPlatforms.AnyUnix)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. + [PlatformSpecific(TestPlatforms.AnyUnix)] [Theory] [InlineData(AddressFamily.InterNetwork)] [InlineData(AddressFamily.InterNetworkV6)] @@ -351,26 +307,18 @@ public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_Unix(AddressF return; } - byte[] buffer = TestSettings.PayloadAsBytes; + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + SendBatchPing( (ping) => ping.Send(localIpAddress, TestSettings.PingTimeout, buffer, new PingOptions()), (pingReply) => { PingResultValidator(pingReply, localIpAddress); - - // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - if (Capability.CanUseRawSockets(localIpAddress.AddressFamily) || PlatformDetection.IsOSXLike) - { - Assert.Equal(buffer, pingReply.Buffer); - } - else - { - Assert.Equal(Array.Empty(), pingReply.Buffer); - } + Assert.Equal(buffer, pingReply.Buffer); }); } - [PlatformSpecific(TestPlatforms.AnyUnix)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. + [PlatformSpecific(TestPlatforms.AnyUnix)] [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(AddressFamily.InterNetwork)] [InlineData(AddressFamily.InterNetworkV6)] @@ -383,22 +331,14 @@ public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions_Un return; } - byte[] buffer = TestSettings.PayloadAsBytes; + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + await SendBatchPingAsync( (ping) => ping.SendPingAsync(localIpAddress, TestSettings.PingTimeout, buffer, new PingOptions()), (pingReply) => { PingResultValidator(pingReply, localIpAddress); - - // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - if (Capability.CanUseRawSockets(localIpAddress.AddressFamily) || PlatformDetection.IsOSXLike) - { - Assert.Equal(buffer, pingReply.Buffer); - } - else - { - Assert.Equal(Array.Empty(), pingReply.Buffer); - } + Assert.Equal(buffer, pingReply.Buffer); }); } @@ -454,13 +394,12 @@ await SendBatchPingAsync( }); } - [PlatformSpecific(TestPlatforms.Windows)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. [Fact] public void SendPingWithHostAndTimeoutAndBuffer() { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - byte[] buffer = TestSettings.PayloadAsBytes; SendBatchPing( (ping) => ping.Send(TestSettings.LocalHost, TestSettings.PingTimeout, buffer), (pingReply) => @@ -470,13 +409,12 @@ public void SendPingWithHostAndTimeoutAndBuffer() }); } - [PlatformSpecific(TestPlatforms.Windows)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithHostAndTimeoutAndBuffer() { IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - byte[] buffer = TestSettings.PayloadAsBytes; await SendBatchPingAsync( (ping) => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer), (pingReply) => @@ -486,80 +424,27 @@ await SendBatchPingAsync( }); } - [PlatformSpecific(TestPlatforms.AnyUnix)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - [Fact] - public void SendPingWithHostAndTimeoutAndBuffer_Unix() - { - IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); - - byte[] buffer = TestSettings.PayloadAsBytes; - SendBatchPing( - (ping) => ping.Send(TestSettings.LocalHost, TestSettings.PingTimeout, buffer), - (pingReply) => - { - PingResultValidator(pingReply, localIpAddresses); - - // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - if (Capability.CanUseRawSockets(pingReply.Address.AddressFamily) || PlatformDetection.IsOSXLike) - { - Assert.Equal(buffer, pingReply.Buffer); - } - else - { - Assert.Equal(Array.Empty(), pingReply.Buffer); - } - }); - } - - [PlatformSpecific(TestPlatforms.AnyUnix)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsyncWithHostAndTimeoutAndBuffer_Unix() - { - IPAddress[] localIpAddresses = await TestSettings.GetLocalIPAddressesAsync(); - - byte[] buffer = TestSettings.PayloadAsBytes; - await SendBatchPingAsync( - (ping) => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer), - (pingReply) => - { - PingResultValidator(pingReply, localIpAddresses); - - // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - if (Capability.CanUseRawSockets(pingReply.Address.AddressFamily) || PlatformDetection.IsOSXLike) - { - Assert.Equal(buffer, pingReply.Buffer); - } - else - { - Assert.Equal(Array.Empty(), pingReply.Buffer); - } - }); - } - - [PlatformSpecific(TestPlatforms.Windows)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. [Fact] public void SendPingWithHostAndTimeoutAndBufferAndPingOptions() { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - byte[] buffer = TestSettings.PayloadAsBytes; SendBatchPing( (ping) => ping.Send(TestSettings.LocalHost, TestSettings.PingTimeout, buffer, new PingOptions()), (pingReply) => { PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); }); } - [PlatformSpecific(TestPlatforms.Windows)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithHostAndTimeoutAndBufferAndPingOptions() { IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - byte[] buffer = TestSettings.PayloadAsBytes; await SendBatchPingAsync( (ping) => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer, new PingOptions()), (pingReply) => @@ -570,57 +455,7 @@ await SendBatchPingAsync( }); } - [PlatformSpecific(TestPlatforms.AnyUnix)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - [Fact] - public void SendPingWithHostAndTimeoutAndBufferAndPingOptions_Unix() - { - IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); - - byte[] buffer = TestSettings.PayloadAsBytes; - SendBatchPing( - (ping) => ping.Send(TestSettings.LocalHost, TestSettings.PingTimeout, buffer, new PingOptions()), - (pingReply) => - { - PingResultValidator(pingReply, localIpAddresses); - - // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - if (Capability.CanUseRawSockets(pingReply.Address.AddressFamily) || PlatformDetection.IsOSXLike) - { - Assert.Equal(buffer, pingReply.Buffer); - } - else - { - Assert.Equal(Array.Empty(), pingReply.Buffer); - } - }); - } - - [PlatformSpecific(TestPlatforms.AnyUnix)] // On Unix, Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsyncWithHostAndTimeoutAndBufferAndPingOptions_Unix() - { - IPAddress[] localIpAddresses = await TestSettings.GetLocalIPAddressesAsync(); - - byte[] buffer = TestSettings.PayloadAsBytes; - await SendBatchPingAsync( - (ping) => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer, new PingOptions()), - (pingReply) => - { - PingResultValidator(pingReply, localIpAddresses); - - // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. - if (Capability.CanUseRawSockets(pingReply.Address.AddressFamily) || PlatformDetection.IsOSXLike) - { - Assert.Equal(buffer, pingReply.Buffer); - } - else - { - Assert.Equal(Array.Empty(), pingReply.Buffer); - } - }); - } - - [Fact] + [ConditionalFact(nameof(DoesNotUsePingUtility))] public async Task SendPingWithIPAddressAndBigSize() { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); @@ -635,8 +470,7 @@ public async Task SendPingWithIPAddressAndBigSize() // // On Windows 10 the maximum ping size seems essentially limited to 65500 bytes and thus any buffer // size on the loopback ping succeeds. On macOS anything bigger than 8184 will report packet too - // big error. On Linux/Unix the result differs for privileged and unprivileged processes and may - // change with different platform versions. + // big error. if (OperatingSystem.IsMacOS()) { Assert.Equal(IPStatus.PacketTooBig, pingReply.Status); @@ -813,7 +647,7 @@ public async Task SendPingAsyncWithHostAndTtlAndFragmentPingOptions(bool fragmen { IPAddress[] localIpAddresses = await TestSettings.GetLocalIPAddressesAsync(); - byte[] buffer = TestSettings.PayloadAsBytes; + byte[] buffer = GetPingPayload(localIpAddresses[0].AddressFamily); PingOptions options = new PingOptions(); options.Ttl = 32; @@ -1003,5 +837,25 @@ await SendBatchPingAsync( }); }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); } + + [ConditionalFact(nameof(UsesPingUtility))] + public void SendPing_CustomPayload_InsufficientPrivileges_Throws() + { + IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); + + byte[] buffer = TestSettings.PayloadAsBytes; + Ping ping = new Ping(); + Assert.Throws(() => ping.Send(TestSettings.LocalHost, TestSettings.PingTimeout, buffer)); + } + + [ConditionalFact(nameof(UsesPingUtility))] + public async Task SendPingAsync_CustomPayload_InsufficientPrivileges_Throws() + { + IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); + + byte[] buffer = TestSettings.PayloadAsBytes; + Ping ping = new Ping(); + await Assert.ThrowsAsync(() => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer)); + } } } diff --git a/src/libraries/System.Net.Primitives/src/Resources/Strings.resx b/src/libraries/System.Net.Primitives/src/Resources/Strings.resx index d95ea7484aace1..087b59a63b2e49 100644 --- a/src/libraries/System.Net.Primitives/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Primitives/src/Resources/Strings.resx @@ -114,4 +114,7 @@ An invalid IPEndPoint was specified. + + System.Net.Primitives is not supported on this platform. + diff --git a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj index 39c385c8dbc123..cbb369186fa279 100644 --- a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj +++ b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj @@ -2,15 +2,18 @@ true false - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) enable - - $(DefineConstants);SYSTEM_NET_PRIMITIVES_DLL - + + + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) + SR.PlatformNotSupported_NetPrimitives + + diff --git a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj index 7017d01e08a0af..8069716509de41 100644 --- a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj +++ b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj @@ -128,8 +128,8 @@ - + diff --git a/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj b/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj index 0de5ec949fbe1c..fabcc644d972aa 100644 --- a/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj +++ b/src/libraries/System.Net.Requests/src/System.Net.Requests.csproj @@ -1,16 +1,18 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent) $(NoWarn);SYSLIB0014 enable + - SR.SystemNetRequests_PlatformNotSupported + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) + SR.SystemNetRequests_PlatformNotSupported $(NoWarn);CS0809 - + @@ -106,7 +108,7 @@ - + diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 047cbdcc98aea9..d665d21b9ba06f 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -409,8 +409,6 @@ - - @@ -427,8 +425,10 @@ + + diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs index 4bd1b0ee30f9a2..4b4dcaf9b6ae98 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs @@ -27,7 +27,7 @@ internal static class TestConfiguration public const string NtlmUserFilePath = "/var/tmp/ntlm_user_file"; public static bool SupportsNullEncryption { get { return s_supportsNullEncryption.Value; } } - public static bool SupportsHandshakeAlerts { get { return OperatingSystem.IsLinux() || OperatingSystem.IsWindows(); } } + public static bool SupportsHandshakeAlerts { get { return OperatingSystem.IsLinux() || OperatingSystem.IsWindows() || OperatingSystem.IsFreeBSD(); } } public static bool SupportsRenegotiation { get { return (OperatingSystem.IsWindows() && !PlatformDetection.IsWindows7) || ((OperatingSystem.IsLinux() || OperatingSystem.IsFreeBSD()) && PlatformDetection.OpenSslVersion >= new Version(1, 1, 1)); } } public static Task WhenAllOrAnyFailedWithTimeout(params Task[] tasks) diff --git a/src/libraries/System.Net.ServicePoint/src/System.Net.ServicePoint.csproj b/src/libraries/System.Net.ServicePoint/src/System.Net.ServicePoint.csproj index 54aae967357154..b67c9ae2f0d416 100644 --- a/src/libraries/System.Net.ServicePoint/src/System.Net.ServicePoint.csproj +++ b/src/libraries/System.Net.ServicePoint/src/System.Net.ServicePoint.csproj @@ -18,6 +18,6 @@ - + diff --git a/src/libraries/System.Net.ServicePoint/tests/ServicePointManagerTest.cs b/src/libraries/System.Net.ServicePoint/tests/ServicePointManagerTest.cs index fac9de7a8e869d..b132ae14edf725 100644 --- a/src/libraries/System.Net.ServicePoint/tests/ServicePointManagerTest.cs +++ b/src/libraries/System.Net.ServicePoint/tests/ServicePointManagerTest.cs @@ -284,6 +284,7 @@ public static void FindServicePoint_ReturnsCachedServicePoint() [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [ActiveIssue("https://github.com/dotnet/runtime/issues/36217", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoInterpreter))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64674", typeof(PlatformDetection), nameof(PlatformDetection.IsArmv6Process))] public static void FindServicePoint_Collectible() { RemoteExecutor.Invoke(() => diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs index 70205f8033cc49..f7475703b3da10 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs @@ -84,6 +84,7 @@ public async Task Datagram_UDP_ShouldImplicitlyBindLocalEndpoint() } [Fact] + [SkipOnPlatform(TestPlatforms.FreeBSD, "FreeBSD allows sendto() to broadcast")] public async Task Datagram_UDP_AccessDenied_Throws_DoesNotBind() { IPEndPoint invalidEndpoint = new IPEndPoint(IPAddress.Broadcast, 1234); diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs index 2c0ec09e6a6cf5..e691520ce5b5f2 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs @@ -587,7 +587,6 @@ public void AcceptAsync_WithReceiveBuffer_Success() } } - [OuterLoop] [Fact] [PlatformSpecific(TestPlatforms.Windows)] // Unix platforms don't yet support receiving data with AcceptAsync. public void AcceptAsync_WithTooSmallReceiveBuffer_Failure() @@ -604,7 +603,7 @@ public void AcceptAsync_WithTooSmallReceiveBuffer_Failure() byte[] buffer = new byte[1]; acceptArgs.SetBuffer(buffer, 0, buffer.Length); - AssertExtensions.Throws(null, () => server.AcceptAsync(acceptArgs)); + AssertExtensions.Throws("Count", () => server.AcceptAsync(acceptArgs)); } } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketOptionNameTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketOptionNameTest.cs index 0bf9bdd45688f4..2d87c58b45905a 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketOptionNameTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketOptionNameTest.cs @@ -504,7 +504,7 @@ public void SetIPProtectionLevel_ArgumentException(AddressFamily family) } } - [Theory] + [ConditionalTheory] [InlineData(AddressFamily.InterNetwork)] [InlineData(AddressFamily.InterNetworkV6)] [ActiveIssue("https://github.com/dotnet/runtime/issues/50568", TestPlatforms.Android)] @@ -515,6 +515,7 @@ public void GetSetRawSocketOption_Roundtrips(AddressFamily family) int SO_RCVBUF; if (OperatingSystem.IsWindows() || + OperatingSystem.IsFreeBSD() || OperatingSystem.IsMacOS()) { SOL_SOCKET = 0xffff; @@ -558,7 +559,7 @@ public void Get_AcceptConnection_Succeeds() s.Bind(new IPEndPoint(IPAddress.Loopback, 0)); s.Listen(); - Assert.Equal(1, s.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.AcceptConnection)); + Assert.NotEqual(0, s.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.AcceptConnection)); } } diff --git a/src/libraries/System.Net.WebSockets/src/Resources/Strings.resx b/src/libraries/System.Net.WebSockets/src/Resources/Strings.resx index e96ac19e3f8ef4..24f8e00b44f217 100644 --- a/src/libraries/System.Net.WebSockets/src/Resources/Strings.resx +++ b/src/libraries/System.Net.WebSockets/src/Resources/Strings.resx @@ -168,4 +168,7 @@ The WebSocket received a frame with an invalid payload length. + + WebSockets is not supported on this platform. + diff --git a/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj b/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj index d1983aa0c10b9a..9f2c2cc09cdaf0 100644 --- a/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj +++ b/src/libraries/System.Net.WebSockets/src/System.Net.WebSockets.csproj @@ -1,10 +1,15 @@ True - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) enable - + + + $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) + SR.PlatformNotSupported_WebSockets + + diff --git a/src/libraries/System.Numerics.Vectors/System.Numerics.Vectors.sln b/src/libraries/System.Numerics.Vectors/System.Numerics.Vectors.sln index 8bb2aa3fc8c114..c829f21df46ba7 100644 --- a/src/libraries/System.Numerics.Vectors/System.Numerics.Vectors.sln +++ b/src/libraries/System.Numerics.Vectors/System.Numerics.Vectors.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Numerics.Vectors", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Numerics.Vectors.Tests", "tests\System.Numerics.Vectors.Tests.csproj", "{B38797B1-BB45-4B30-9D4F-79D9F4B3735B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{88F4A78E-4EF9-4EB6-995E-CD24152C4704}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{88F4A78E-4EF9-4EB6-995E-CD24152C4704}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{DFC21F4E-EC4F-4310-A4DA-B7094AA4D237}" EndProject diff --git a/src/libraries/System.Private.CoreLib/generators/EventSourceGenerator.Emitter.cs b/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Emitter.cs similarity index 96% rename from src/libraries/System.Private.CoreLib/generators/EventSourceGenerator.Emitter.cs rename to src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Emitter.cs index d855d34634b1e0..894ae45816ad38 100644 --- a/src/libraries/System.Private.CoreLib/generators/EventSourceGenerator.Emitter.cs +++ b/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Emitter.cs @@ -32,7 +32,7 @@ public void Emit(EventSourceClass[] eventSources, CancellationToken cancellation _builder.AppendLine("using System;"); GenType(ec); - _context.AddSource($"{ec.ClassName}.Generated", SourceText.From(_builder.ToString(), Encoding.UTF8)); + _context.AddSource($"{ec.ClassName}.g.cs", SourceText.From(_builder.ToString(), Encoding.UTF8)); _builder.Clear(); } diff --git a/src/libraries/System.Private.CoreLib/generators/EventSourceGenerator.Parser.cs b/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Parser.cs similarity index 100% rename from src/libraries/System.Private.CoreLib/generators/EventSourceGenerator.Parser.cs rename to src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Parser.cs diff --git a/src/libraries/System.Private.CoreLib/generators/EventSourceGenerator.cs b/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.cs similarity index 100% rename from src/libraries/System.Private.CoreLib/generators/EventSourceGenerator.cs rename to src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.cs diff --git a/src/libraries/System.Private.CoreLib/generators/System.Private.CoreLib.Generators.csproj b/src/libraries/System.Private.CoreLib/gen/System.Private.CoreLib.Generators.csproj similarity index 68% rename from src/libraries/System.Private.CoreLib/generators/System.Private.CoreLib.Generators.csproj rename to src/libraries/System.Private.CoreLib/gen/System.Private.CoreLib.Generators.csproj index 451bb520f66ead..6ce771f7124a87 100644 --- a/src/libraries/System.Private.CoreLib/generators/System.Private.CoreLib.Generators.csproj +++ b/src/libraries/System.Private.CoreLib/gen/System.Private.CoreLib.Generators.csproj @@ -6,16 +6,16 @@ false $(NoWarn);CS3001 - - - - - - - + + + + + + + diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index f5d5b0061f06d2..a29b249ea668bc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -258,7 +258,9 @@ private static void FixDefaultShortDatePattern(List shortDatePatterns) /// private static string NormalizeDatePattern(string input) { - StringBuilder destination = StringBuilderCache.Acquire(input.Length); + var destination = input.Length < 128 ? + new ValueStringBuilder(stackalloc char[128]) : + new ValueStringBuilder(input.Length); int index = 0; while (index < input.Length) @@ -287,7 +289,7 @@ private static string NormalizeDatePattern(string input) // maps closest to 3 or 4 'd's in .NET // 'c' in ICU is the stand-alone day of the week, which has no representation in .NET, but // maps closest to 3 or 4 'd's in .NET - NormalizeDayOfWeek(input, destination, ref index); + NormalizeDayOfWeek(input, ref destination, ref index); break; case 'L': case 'M': @@ -332,10 +334,10 @@ private static string NormalizeDatePattern(string input) } } - return StringBuilderCache.GetStringAndRelease(destination); + return destination.ToString(); } - private static void NormalizeDayOfWeek(string input, StringBuilder destination, ref int index) + private static void NormalizeDayOfWeek(string input, ref ValueStringBuilder destination, ref int index) { char dayChar = input[index]; int occurrences = CountOccurrences(input, dayChar, ref index); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs index 6020e84411bf3a..e993a17abba248 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs @@ -4226,12 +4226,12 @@ private static bool ParseByFormat( break; case '\"': case '\'': - StringBuilder enquotedString = StringBuilderCache.Acquire(); + var enquotedString = new ValueStringBuilder(stackalloc char[128]); // Use ParseQuoteString so that we can handle escape characters within the quoted string. - if (!TryParseQuoteString(format.Value, format.Index, enquotedString, out tokenLen)) + if (!TryParseQuoteString(format.Value, format.Index, ref enquotedString, out tokenLen)) { result.SetFailure(ParseFailureKind.FormatWithParameter, nameof(SR.Format_BadQuote), ch); - StringBuilderCache.Release(enquotedString); + enquotedString.Dispose(); return false; } format.Index += tokenLen - 1; @@ -4239,7 +4239,7 @@ private static bool ParseByFormat( // Some cultures uses space in the quoted string. E.g. Spanish has long date format as: // "dddd, dd' de 'MMMM' de 'yyyy". When inner spaces flag is set, we should skip whitespaces if there is space // in the quoted string. - string quotedStr = StringBuilderCache.GetStringAndRelease(enquotedString); + string quotedStr = enquotedString.ToString(); for (int i = 0; i < quotedStr.Length; i++) { @@ -4385,18 +4385,14 @@ private static bool ParseByFormat( // The pos should point to a quote character. This method will // get the string enclosed by the quote character. // - internal static bool TryParseQuoteString(ReadOnlySpan format, int pos, StringBuilder result, out int returnValue) + internal static bool TryParseQuoteString(ReadOnlySpan format, int pos, ref ValueStringBuilder result, out int returnValue) { - // - // NOTE : pos will be the index of the quote character in the 'format' string. - // - returnValue = 0; - int formatLen = format.Length; + // NOTE: pos will be the index of the quote character in the 'format' string. int beginPos = pos; char quoteChar = format[pos++]; // Get the character used to quote the following string. bool foundQuote = false; - while (pos < formatLen) + while ((uint)pos < (uint)format.Length) { char ch = format[pos++]; if (ch == quoteChar) @@ -4411,15 +4407,14 @@ internal static bool TryParseQuoteString(ReadOnlySpan format, int pos, Str // Therefore, someone can use a format like "'minute:' mm\"" to display: // minute: 45" // because the second double quote is escaped. - if (pos < formatLen) + if ((uint)pos < (uint)format.Length) { result.Append(format[pos++]); } else { - // // This means that '\' is at the end of the formatting string. - // + returnValue = 0; return false; } } @@ -4432,6 +4427,7 @@ internal static bool TryParseQuoteString(ReadOnlySpan format, int pos, Str if (!foundQuote) { // Here we can't find the matching quote. + returnValue = 0; return false; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanParse.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanParse.cs index 0eb7fd2fc20f3f..ec5e39f76938d3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanParse.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanParse.cs @@ -246,15 +246,12 @@ internal void BackOne() if (_pos > 0) --_pos; } - internal char NextChar + internal char NextChar() { - get - { - int pos = ++_pos; - return (uint)pos < (uint)_value.Length ? - _value[pos] : - (char)0; - } + int pos = ++_pos; + return (uint)pos < (uint)_value.Length? + _value[pos] : + (char)0; } } @@ -1261,7 +1258,7 @@ private static bool TryParseByFormat(ReadOnlySpan input, ReadOnlySpan input, ReadOnlySpan input, ReadOnlySpan= 0 && tokenizer.NextChar == (char)nextFormatChar) + if (nextFormatChar >= 0 && tokenizer.NextChar() == (char)nextFormatChar) { tokenLen = 2; } @@ -1423,7 +1420,7 @@ private static bool ParseExactDigits(ref TimeSpanTokenizer tokenizer, int minDig int tokenLength = 0; while (tokenLength < maxDigitLength) { - char ch = tokenizer.NextChar; + char ch = tokenizer.NextChar(); if (ch < '0' || ch > '9') { tokenizer.BackOne(); @@ -1440,11 +1437,12 @@ private static bool ParseExactDigits(ref TimeSpanTokenizer tokenizer, int minDig return tokenLength >= minDigitLength; } - private static bool ParseExactLiteral(ref TimeSpanTokenizer tokenizer, StringBuilder enquotedString) + private static bool ParseExactLiteral(ref TimeSpanTokenizer tokenizer, ref ValueStringBuilder enquotedString) { - for (int i = 0; i < enquotedString.Length; i++) + ReadOnlySpan span = enquotedString.AsSpan(); + for (int i = 0; i < span.Length; i++) { - if (enquotedString[i] != tokenizer.NextChar) + if (span[i] != tokenizer.NextChar()) { return false; } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs index 772440a293a52f..c3a06c618bf813 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs @@ -13,6 +13,15 @@ public static partial class Path public static char[] GetInvalidPathChars() => new char[] { '\0' }; + // Checks if the given path is available for use. + private static bool ExistsCore(string fullPath, out bool isDirectory) + { + bool result = Interop.Sys.LStat(fullPath, out Interop.Sys.FileStatus fileInfo) == Interop.Errors.ERROR_SUCCESS; + isDirectory = result && (fileInfo.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR; + + return result; + } + // Expands the given path to a fully qualified path. public static string GetFullPath(string path) { diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Windows.cs index b10cedd4ecbdd2..655a70719b845e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Windows.cs @@ -27,6 +27,16 @@ public static partial class Path (char)31 }; + private static bool ExistsCore(string fullPath, out bool isDirectory) + { + Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA data = default; + int errorCode = FileSystem.FillAttributeInfo(fullPath, ref data, returnErrorOnNotFound: true); + bool result = (errorCode == Interop.Errors.ERROR_SUCCESS) && (data.dwFileAttributes != -1); + isDirectory = result && (data.dwFileAttributes & Interop.Kernel32.FileAttributes.FILE_ATTRIBUTE_DIRECTORY) != 0; + + return result; + } + // Expands the given path to a fully qualified path. public static string GetFullPath(string path) { diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs index b2887383294eb5..da52cdfd81e024 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs @@ -75,6 +75,49 @@ public static partial class Path string.Concat(subpath, ".", extension); } + /// + /// Determines whether the specified file or directory exists. + /// + /// + /// Unlike it returns true for existing, non-regular files like pipes. + /// If the path targets an existing link, but the target of the link does not exist, it returns true. + /// + /// The path to check + /// + /// if the caller has the required permissions and contains + /// the name of an existing file or directory; otherwise, . + /// This method also returns if is , + /// an invalid path, or a zero-length string. If the caller does not have sufficient permissions to read the specified path, + /// no exception is thrown and the method returns regardless of the existence of . + /// + public static bool Exists([NotNullWhen(true)] string? path) + { + if (string.IsNullOrEmpty(path)) + { + return false; + } + + string? fullPath; + try + { + fullPath = GetFullPath(path); + } + catch (Exception ex) when (ex is ArgumentException or IOException or UnauthorizedAccessException) + { + return false; + } + + bool result = ExistsCore(fullPath, out bool isDirectory); + if (result && PathInternal.IsDirectorySeparator(fullPath[fullPath.Length - 1])) + { + // Some sys-calls remove all trailing slashes and may give false positives for existing files. + // We want to make sure that if the path ends in a trailing slash, it's truly a directory. + return isDirectory; + } + + return result; + } + /// /// Returns the directory portion of a file path. This method effectively /// removes the last segment of the given file path, i.e. it returns a diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs index c591e51f15e232..656739a7c855e7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs @@ -509,23 +509,16 @@ public override void WriteLine(ReadOnlySpan buffer) private void WriteFormatHelper(string format, ParamsArray args, bool appendNewLine) { - StringBuilder sb = - StringBuilderCache.Acquire((format?.Length ?? 0) + args.Length * 8) - .AppendFormatHelper(null, format!, args); // AppendFormatHelper will appropriately throw ArgumentNullException for a null format + int estimatedLength = (format?.Length ?? 0) + args.Length * 8; + var vsb = estimatedLength <= 256 ? + new ValueStringBuilder(stackalloc char[256]) : + new ValueStringBuilder(estimatedLength); - StringBuilder.ChunkEnumerator chunks = sb.GetChunks(); + vsb.AppendFormatHelper(null, format!, args); // AppendFormatHelper will appropriately throw ArgumentNullException for a null format - bool more = chunks.MoveNext(); - while (more) - { - ReadOnlySpan current = chunks.Current.Span; - more = chunks.MoveNext(); - - // If final chunk, include the newline if needed - WriteSpan(current, appendNewLine: more ? false : appendNewLine); - } + WriteSpan(vsb.AsSpan(), appendNewLine); - StringBuilderCache.Release(sb); + vsb.Dispose(); } public override void Write(string format, object? arg0) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index f5a4becbd73b40..6b5c05d37231bd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -260,7 +260,21 @@ internal sealed class ContingentProperties internal void SetCompleted() { ManualResetEventSlim? mres = m_completionEvent; - if (mres != null) mres.Set(); + if (mres != null) SetEvent(mres); + } + + internal static void SetEvent(ManualResetEventSlim mres) + { + try + { + mres.Set(); + } + catch (ObjectDisposedException) + { + // The event may have been exposed to external code, in which case it could have been disposed + // prematurely / erroneously. To avoid that causing problems for the unrelated stack trying to + // set the event, eat any disposed exceptions. + } } /// @@ -1483,7 +1497,7 @@ internal ManualResetEventSlim CompletedEvent { // We published the event as unset, but the task has subsequently completed. // Set the event's state properly so that callers don't deadlock. - newMre.Set(); + ContingentProperties.SetEvent(newMre); } } @@ -1619,7 +1633,7 @@ protected virtual void Dispose(bool disposing) // will deadlock; an ensuing Set() will not wake them up. In the event of an AppDomainUnload, // there is no guarantee that anyone else is going to signal the event, and it does no harm to // call Set() twice on m_completionEvent. - if (!ev.IsSet) ev.Set(); + ContingentProperties.SetEvent(ev); // Finally, dispose of the event ev.Dispose(); diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System.Private.Runtime.InteropServices.JavaScript.csproj b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System.Private.Runtime.InteropServices.JavaScript.csproj index e6991801ba5c99..610fe2b087683a 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System.Private.Runtime.InteropServices.JavaScript.csproj +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System.Private.Runtime.InteropServices.JavaScript.csproj @@ -5,7 +5,7 @@ $(NetCoreAppCurrent)-Browser $(NoWarn);CA1419 - + @@ -33,12 +33,10 @@ - - - + diff --git a/src/libraries/System.Private.Uri/System.Private.Uri.sln b/src/libraries/System.Private.Uri/System.Private.Uri.sln index b587b756d2a326..f4a11693f0f1a7 100644 --- a/src/libraries/System.Private.Uri/System.Private.Uri.sln +++ b/src/libraries/System.Private.Uri/System.Private.Uri.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{ADD88187-83E2-4EAF-BFB4-BC6249E76457}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{D9F21DA7-0FE6-419E-9CE3-DFFBC3F0067F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{D9F21DA7-0FE6-419E-9CE3-DFFBC3F0067F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Uri", "src\System.Private.Uri.csproj", "{98AC821B-892E-4F58-AF3D-503747FD6A8F}" EndProject diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/System.Reflection.Emit.ILGeneration.sln b/src/libraries/System.Reflection.Emit.ILGeneration/System.Reflection.Emit.ILGeneration.sln index a5f973233c87a6..2ba9f755e9b36c 100644 --- a/src/libraries/System.Reflection.Emit.ILGeneration/System.Reflection.Emit.ILGeneration.sln +++ b/src/libraries/System.Reflection.Emit.ILGeneration/System.Reflection.Emit.ILGeneration.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{05696F45-ACF1-4C02-B8D9-E8C1F5E28717}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{8843EA69-AD8F-4C73-8436-1641470199DC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{8843EA69-AD8F-4C73-8436-1641470199DC}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.Emit.ILGeneration", "ref\System.Reflection.Emit.ILGeneration.csproj", "{64BBA40A-8DB5-4829-815A-3D612A12222D}" EndProject diff --git a/src/libraries/System.Reflection.Emit.Lightweight/System.Reflection.Emit.Lightweight.sln b/src/libraries/System.Reflection.Emit.Lightweight/System.Reflection.Emit.Lightweight.sln index ca25c8d54e2138..9e3961834d75bc 100644 --- a/src/libraries/System.Reflection.Emit.Lightweight/System.Reflection.Emit.Lightweight.sln +++ b/src/libraries/System.Reflection.Emit.Lightweight/System.Reflection.Emit.Lightweight.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{ECDDE645-347C-46D8-B6B6-BCFF6B9AFD4A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{165A3077-1F79-46E7-8BFA-88AACEB6D026}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{165A3077-1F79-46E7-8BFA-88AACEB6D026}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.Emit.Lightweight", "ref\System.Reflection.Emit.Lightweight.csproj", "{EE535D8F-D21B-4C18-A915-60E94CE19CA2}" EndProject diff --git a/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln b/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln index 3df342146ed984..8de9514ee80f93 100644 --- a/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln +++ b/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{E5543842-139D-43BD-B604-E65EBB91649E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{848EFB55-86B5-4259-BAA2-A49C6E3421A9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{848EFB55-86B5-4259-BAA2-A49C6E3421A9}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.Emit", "ref\System.Reflection.Emit.csproj", "{6A176C5B-206D-4550-AC36-0530218E29F5}" EndProject diff --git a/src/libraries/System.Reflection.Primitives/System.Reflection.Primitives.sln b/src/libraries/System.Reflection.Primitives/System.Reflection.Primitives.sln index ca3ef75888d49d..ba25a1eed4148a 100644 --- a/src/libraries/System.Reflection.Primitives/System.Reflection.Primitives.sln +++ b/src/libraries/System.Reflection.Primitives/System.Reflection.Primitives.sln @@ -1,7 +1,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "..\..\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj", "{661E0A3D-E151-45B2-AA38-B30F8227A741}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{869B6F76-2329-474A-854E-5AD5541A1CA0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{869B6F76-2329-474A-854E-5AD5541A1CA0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.Primitives", "ref\System.Reflection.Primitives.csproj", "{9D308994-9721-4883-B32D-531FA8D9025B}" EndProject diff --git a/src/libraries/System.Reflection.TypeExtensions/System.Reflection.TypeExtensions.sln b/src/libraries/System.Reflection.TypeExtensions/System.Reflection.TypeExtensions.sln index 191d6b72d8b91f..0da0851f8cdcdc 100644 --- a/src/libraries/System.Reflection.TypeExtensions/System.Reflection.TypeExtensions.sln +++ b/src/libraries/System.Reflection.TypeExtensions/System.Reflection.TypeExtensions.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{41438432-4DC0-4724-8C8F-0D100083490F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{EAE41D82-CFFA-4934-89B2-399D12530E84}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{EAE41D82-CFFA-4934-89B2-399D12530E84}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.TypeExtensions", "ref\System.Reflection.TypeExtensions.csproj", "{03C0F6B8-A04B-4822-8089-3918F02AD281}" EndProject diff --git a/src/libraries/System.Reflection/System.Reflection.sln b/src/libraries/System.Reflection/System.Reflection.sln index cebe8e01ca6fe1..3468ce901b0b9b 100644 --- a/src/libraries/System.Reflection/System.Reflection.sln +++ b/src/libraries/System.Reflection/System.Reflection.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{C5A7E7E7-E43B-4C87-9A92-13C3C817E714}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{1F5C28EE-FA69-4A3A-934C-88FEBBDE2489}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{1F5C28EE-FA69-4A3A-934C-88FEBBDE2489}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection", "ref\System.Reflection.csproj", "{319997BC-5DF6-4E23-A768-ED9905690EF4}" EndProject diff --git a/src/libraries/System.Resources.ResourceManager/System.Resources.ResourceManager.sln b/src/libraries/System.Resources.ResourceManager/System.Resources.ResourceManager.sln index 810affea078cae..3e94c9048841f1 100644 --- a/src/libraries/System.Resources.ResourceManager/System.Resources.ResourceManager.sln +++ b/src/libraries/System.Resources.ResourceManager/System.Resources.ResourceManager.sln @@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Drawing.Common", ".. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Drawing.Common", "..\System.Drawing.Common\src\System.Drawing.Common.csproj", "{00F48AD2-CCF6-4F52-A63E-AC2D00574375}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{497FC2E7-EFA3-4F6F-A883-527900B60D4F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{497FC2E7-EFA3-4F6F-A883-527900B60D4F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Resources.Extensions", "..\System.Resources.Extensions\ref\System.Resources.Extensions.csproj", "{F98F08E3-520B-49CA-B038-FF20857CEAA7}" EndProject diff --git a/src/libraries/System.Runtime.Caching/NuGet.config b/src/libraries/System.Runtime.Caching/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Runtime.Caching/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Runtime.Caching/src/System.Runtime.Caching.csproj b/src/libraries/System.Runtime.Caching/src/System.Runtime.Caching.csproj index 8742a91f18a16c..a567a23967c5da 100644 --- a/src/libraries/System.Runtime.Caching/src/System.Runtime.Caching.csproj +++ b/src/libraries/System.Runtime.Caching/src/System.Runtime.Caching.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0-windows;netstandard2.0 + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0 true Annotations true diff --git a/src/libraries/System.Runtime.Extensions/System.Runtime.Extensions.sln b/src/libraries/System.Runtime.Extensions/System.Runtime.Extensions.sln index d19cfb44381f98..6ad1a98fa338b1 100644 --- a/src/libraries/System.Runtime.Extensions/System.Runtime.Extensions.sln +++ b/src/libraries/System.Runtime.Extensions/System.Runtime.Extensions.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{D7A1E176-1515-41FE-86D0-A46C82B87B05}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{C7112A41-1DC9-421E-88A0-8830D081A7B1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{C7112A41-1DC9-421E-88A0-8830D081A7B1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Uri", "..\System.Private.Uri\src\System.Private.Uri.csproj", "{1E0C4DD8-3A04-4B4C-9699-DB5844F2CFB2}" EndProject diff --git a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs index 8c6fc1a78d47bf..7ec508517e01cb 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs @@ -190,7 +190,8 @@ public void OSVersion_ValidVersion_OSX() Version version = Environment.OSVersion.Version; // verify that the Environment.OSVersion.Version matches the current RID - Assert.Contains(version.ToString(2), RuntimeInformation.RuntimeIdentifier); + // As of 12.0, only major version numbers are included in the RID + Assert.Contains(version.ToString(1), RuntimeInformation.RuntimeIdentifier); Assert.True(version.Build >= 0, "OSVersion Build should be non-negative"); Assert.Equal(-1, version.Revision); // Revision is never set on OSX diff --git a/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln b/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln index 54f3e3fb53c735..9886a7bf529063 100644 --- a/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln +++ b/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln @@ -7,7 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{1B248B4C-7584-4C04-850A-A50EB592052C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{1B248B4C-7584-4C04-850A-A50EB592052C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{5BB5F99F-1052-4EB4-B12E-7863805661F3}" EndProject diff --git a/src/libraries/System.Runtime.Intrinsics/System.Runtime.Intrinsics.sln b/src/libraries/System.Runtime.Intrinsics/System.Runtime.Intrinsics.sln index 3d67228e11b2f6..d9947df29f2fea 100644 --- a/src/libraries/System.Runtime.Intrinsics/System.Runtime.Intrinsics.sln +++ b/src/libraries/System.Runtime.Intrinsics/System.Runtime.Intrinsics.sln @@ -5,7 +5,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities.Unicode", ".. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{EFF55B56-D92B-4573-94EA-AF5B3B001C34}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{A4058388-97C1-492A-86A4-5240C4166BFF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{A4058388-97C1-492A-86A4-5240C4166BFF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{1CE54DEE-4025-41A8-B8FE-D8380EA988B1}" EndProject diff --git a/src/libraries/System.Runtime.Loader/System.Runtime.Loader.sln b/src/libraries/System.Runtime.Loader/System.Runtime.Loader.sln index aa3df489270c43..a208e44f3ce497 100644 --- a/src/libraries/System.Runtime.Loader/System.Runtime.Loader.sln +++ b/src/libraries/System.Runtime.Loader/System.Runtime.Loader.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{D6D16FFD-FD76-4700-B456-1DC4D093D1B5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{BFED65C3-5AF6-4C81-8AE8-7CAC7E4867AE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{BFED65C3-5AF6-4C81-8AE8-7CAC7E4867AE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{8D19CD03-08EE-4574-B798-C658502C0A42}" EndProject diff --git a/src/libraries/System.Runtime.Serialization.Formatters/NuGet.config b/src/libraries/System.Runtime.Serialization.Formatters/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Runtime.Serialization.Formatters/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.sln b/src/libraries/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.sln index f431228e859d35..0418b2531242ff 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.sln +++ b/src/libraries/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.sln @@ -63,7 +63,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.Packaging", "..\S EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.Packaging", "..\System.IO.Packaging\src\System.IO.Packaging.csproj", "{AE592E1E-C5DB-4F81-AD45-31F2F1A6A75B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{30C04925-08A1-4AFC-AE30-D7FA39945A5B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{30C04925-08A1-4AFC-AE30-D7FA39945A5B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Uri", "..\System.Private.Uri\src\System.Private.Uri.csproj", "{1E395137-871B-4D6F-A7DB-C92850FAB0D3}" EndProject diff --git a/src/libraries/System.Runtime/NuGet.config b/src/libraries/System.Runtime/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Runtime/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Runtime/System.Runtime.sln b/src/libraries/System.Runtime/System.Runtime.sln index fc6aec975c8631..4da60dec69eb7d 100644 --- a/src/libraries/System.Runtime/System.Runtime.sln +++ b/src/libraries/System.Runtime/System.Runtime.sln @@ -13,7 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Drawing.Common", ".. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Drawing.Common", "..\System.Drawing.Common\src\System.Drawing.Common.csproj", "{F27DC16B-64F4-4BD7-AF9C-1C76F7ACC88B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{CF79B5AE-38CB-4B80-BF92-CF634C0B7EC3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{CF79B5AE-38CB-4B80-BF92-CF634C0B7EC3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Uri", "..\System.Private.Uri\src\System.Private.Uri.csproj", "{E7A05515-DABE-4C09-83CB-CE84EFDCD4CC}" EndProject diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index cf8690cc422e83..4bd98a48d68db6 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -10725,6 +10725,7 @@ public static partial class Path public static string Combine(params string[] paths) { throw null; } public static bool EndsInDirectorySeparator(System.ReadOnlySpan path) { throw null; } public static bool EndsInDirectorySeparator(string path) { throw null; } + public static bool Exists([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? path) { throw null; } public static System.ReadOnlySpan GetDirectoryName(System.ReadOnlySpan path) { throw null; } public static string? GetDirectoryName(string? path) { throw null; } public static System.ReadOnlySpan GetExtension(System.ReadOnlySpan path) { throw null; } diff --git a/src/libraries/System.Runtime/tests/System/ArrayTests.cs b/src/libraries/System.Runtime/tests/System/ArrayTests.cs index e0108b81f3e57b..372a4b3416388b 100644 --- a/src/libraries/System.Runtime/tests/System/ArrayTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArrayTests.cs @@ -1275,6 +1275,9 @@ public static IEnumerable Copy_SZArray_UnreliableConversion_CanPerform // Interface[] -> Class[] yield return new object[] { new NonGenericInterface1[10], 0, new NonGenericClass1[10], 0, 10, new NonGenericClass1[10] }; + + // object[] -> Int32Enum[] when values are all Int32Enum + yield return new object[] { new object[] { Int32Enum.Case3 }, 0, new Int32Enum[1], 0, 1, new Int32Enum[] { Int32Enum.Case3 } }; } public static IEnumerable Copy_Array_UnreliableConversion_CanPerform_TestData() diff --git a/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs b/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs index cbc795b9af3de8..05b4c65cf29159 100644 --- a/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs +++ b/src/libraries/System.Runtime/tests/System/Reflection/ModuleTests.cs @@ -164,6 +164,7 @@ public void GetField_NullName() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/60558", TestPlatforms.Android)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/64675", typeof(PlatformDetection), nameof(PlatformDetection.IsArmv6Process))] public void GetField() { FieldInfo testInt = TestModule.GetField("TestInt", BindingFlags.Public | BindingFlags.Static); diff --git a/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj b/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj index 5564d351b05419..2b95d0edcd4449 100644 --- a/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj +++ b/src/libraries/System.Security.AccessControl/src/System.Security.AccessControl.csproj @@ -79,12 +79,12 @@ Link="Common\Interop\Interop.DuplicateTokenEx_SafeTokenHandle.cs" /> - + diff --git a/src/libraries/System.Security.Cryptography.Algorithms/NuGet.config b/src/libraries/System.Security.Cryptography.Algorithms/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Security.Cryptography.Algorithms/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.Forwards.cs b/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.Forwards.cs new file mode 100644 index 00000000000000..2bdc10900f7aa9 --- /dev/null +++ b/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.Forwards.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Win32.SafeHandles.SafeNCryptHandle))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Win32.SafeHandles.SafeNCryptProviderHandle))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Win32.SafeHandles.SafeNCryptSecretHandle))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AesCng))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngAlgorithm))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngAlgorithmGroup))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngExportPolicies))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngKey))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngKeyBlobFormat))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngKeyCreationOptions))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngKeyCreationParameters))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngKeyHandleOpenOptions))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngKeyOpenOptions))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngKeyUsages))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngProperty))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngPropertyCollection))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngPropertyOptions))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngUIPolicy))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CngUIProtectionLevels))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DSACng))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECDiffieHellmanCng))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECDiffieHellmanCngPublicKey))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECDiffieHellmanKeyDerivationFunction))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECDsaCng))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECKeyXmlFormat))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSACng))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.TripleDESCng))] diff --git a/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.cs b/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.cs deleted file mode 100644 index 66568a4158949e..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.cs +++ /dev/null @@ -1,390 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// ------------------------------------------------------------------------------ -// Changes to this file must follow the https://aka.ms/api-review process. -// ------------------------------------------------------------------------------ - -namespace Microsoft.Win32.SafeHandles -{ - public abstract partial class SafeNCryptHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid - { - protected SafeNCryptHandle() : base (default(bool)) { } - protected SafeNCryptHandle(System.IntPtr handle, System.Runtime.InteropServices.SafeHandle parentHandle) : base (default(bool)) { } - public override bool IsInvalid { get { throw null; } } - protected override bool ReleaseHandle() { throw null; } - protected abstract bool ReleaseNativeHandle(); - } - public sealed partial class SafeNCryptKeyHandle : Microsoft.Win32.SafeHandles.SafeNCryptHandle - { - public SafeNCryptKeyHandle() { } - public SafeNCryptKeyHandle(System.IntPtr handle, System.Runtime.InteropServices.SafeHandle parentHandle) { } - protected override bool ReleaseNativeHandle() { throw null; } - } - public sealed partial class SafeNCryptProviderHandle : Microsoft.Win32.SafeHandles.SafeNCryptHandle - { - public SafeNCryptProviderHandle() { } - protected override bool ReleaseNativeHandle() { throw null; } - } - public sealed partial class SafeNCryptSecretHandle : Microsoft.Win32.SafeHandles.SafeNCryptHandle - { - public SafeNCryptSecretHandle() { } - protected override bool ReleaseNativeHandle() { throw null; } - } -} -namespace System.Security.Cryptography -{ - public sealed partial class AesCng : System.Security.Cryptography.Aes - { - public AesCng() { } - public AesCng(string keyName) { } - public AesCng(string keyName, System.Security.Cryptography.CngProvider provider) { } - public AesCng(string keyName, System.Security.Cryptography.CngProvider provider, System.Security.Cryptography.CngKeyOpenOptions openOptions) { } - public override byte[] Key { get { throw null; } set { } } - public override int KeySize { get { throw null; } set { } } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - protected override void Dispose(bool disposing) { } - public override void GenerateIV() { } - public override void GenerateKey() { } - } - public sealed partial class CngAlgorithm : System.IEquatable - { - public CngAlgorithm(string algorithm) { } - public string Algorithm { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm ECDiffieHellman { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm ECDiffieHellmanP256 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm ECDiffieHellmanP384 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm ECDiffieHellmanP521 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm ECDsa { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm ECDsaP256 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm ECDsaP384 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm ECDsaP521 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm MD5 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm Rsa { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm Sha1 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm Sha256 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm Sha384 { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithm Sha512 { get { throw null; } } - public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } - public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngAlgorithm? other) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(System.Security.Cryptography.CngAlgorithm? left, System.Security.Cryptography.CngAlgorithm? right) { throw null; } - public static bool operator !=(System.Security.Cryptography.CngAlgorithm? left, System.Security.Cryptography.CngAlgorithm? right) { throw null; } - public override string ToString() { throw null; } - } - public sealed partial class CngAlgorithmGroup : System.IEquatable - { - public CngAlgorithmGroup(string algorithmGroup) { } - public string AlgorithmGroup { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithmGroup DiffieHellman { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithmGroup Dsa { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithmGroup ECDiffieHellman { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithmGroup ECDsa { get { throw null; } } - public static System.Security.Cryptography.CngAlgorithmGroup Rsa { get { throw null; } } - public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } - public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngAlgorithmGroup? other) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(System.Security.Cryptography.CngAlgorithmGroup? left, System.Security.Cryptography.CngAlgorithmGroup? right) { throw null; } - public static bool operator !=(System.Security.Cryptography.CngAlgorithmGroup? left, System.Security.Cryptography.CngAlgorithmGroup? right) { throw null; } - public override string ToString() { throw null; } - } - [System.FlagsAttribute] - public enum CngExportPolicies - { - None = 0, - AllowExport = 1, - AllowPlaintextExport = 2, - AllowArchiving = 4, - AllowPlaintextArchiving = 8, - } - public sealed partial class CngKey : System.IDisposable - { - internal CngKey() { } - public System.Security.Cryptography.CngAlgorithm Algorithm { get { throw null; } } - public System.Security.Cryptography.CngAlgorithmGroup? AlgorithmGroup { get { throw null; } } - public System.Security.Cryptography.CngExportPolicies ExportPolicy { get { throw null; } } - public Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle Handle { get { throw null; } } - public bool IsEphemeral { get { throw null; } } - public bool IsMachineKey { get { throw null; } } - public string? KeyName { get { throw null; } } - public int KeySize { get { throw null; } } - public System.Security.Cryptography.CngKeyUsages KeyUsage { get { throw null; } } - public System.IntPtr ParentWindowHandle { get { throw null; } set { } } - public System.Security.Cryptography.CngProvider? Provider { get { throw null; } } - public Microsoft.Win32.SafeHandles.SafeNCryptProviderHandle ProviderHandle { get { throw null; } } - public System.Security.Cryptography.CngUIPolicy UIPolicy { get { throw null; } } - public string? UniqueName { get { throw null; } } - public static System.Security.Cryptography.CngKey Create(System.Security.Cryptography.CngAlgorithm algorithm) { throw null; } - public static System.Security.Cryptography.CngKey Create(System.Security.Cryptography.CngAlgorithm algorithm, string? keyName) { throw null; } - public static System.Security.Cryptography.CngKey Create(System.Security.Cryptography.CngAlgorithm algorithm, string? keyName, System.Security.Cryptography.CngKeyCreationParameters? creationParameters) { throw null; } - public void Delete() { } - public void Dispose() { } - public static bool Exists(string keyName) { throw null; } - public static bool Exists(string keyName, System.Security.Cryptography.CngProvider provider) { throw null; } - public static bool Exists(string keyName, System.Security.Cryptography.CngProvider provider, System.Security.Cryptography.CngKeyOpenOptions options) { throw null; } - public byte[] Export(System.Security.Cryptography.CngKeyBlobFormat format) { throw null; } - public System.Security.Cryptography.CngProperty GetProperty(string name, System.Security.Cryptography.CngPropertyOptions options) { throw null; } - public bool HasProperty(string name, System.Security.Cryptography.CngPropertyOptions options) { throw null; } - public static System.Security.Cryptography.CngKey Import(byte[] keyBlob, System.Security.Cryptography.CngKeyBlobFormat format) { throw null; } - public static System.Security.Cryptography.CngKey Import(byte[] keyBlob, System.Security.Cryptography.CngKeyBlobFormat format, System.Security.Cryptography.CngProvider provider) { throw null; } - public static System.Security.Cryptography.CngKey Open(Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle keyHandle, System.Security.Cryptography.CngKeyHandleOpenOptions keyHandleOpenOptions) { throw null; } - public static System.Security.Cryptography.CngKey Open(string keyName) { throw null; } - public static System.Security.Cryptography.CngKey Open(string keyName, System.Security.Cryptography.CngProvider provider) { throw null; } - public static System.Security.Cryptography.CngKey Open(string keyName, System.Security.Cryptography.CngProvider provider, System.Security.Cryptography.CngKeyOpenOptions openOptions) { throw null; } - public void SetProperty(System.Security.Cryptography.CngProperty property) { } - } - public sealed partial class CngKeyBlobFormat : System.IEquatable - { - public CngKeyBlobFormat(string format) { } - public static System.Security.Cryptography.CngKeyBlobFormat EccFullPrivateBlob { get { throw null; } } - public static System.Security.Cryptography.CngKeyBlobFormat EccFullPublicBlob { get { throw null; } } - public static System.Security.Cryptography.CngKeyBlobFormat EccPrivateBlob { get { throw null; } } - public static System.Security.Cryptography.CngKeyBlobFormat EccPublicBlob { get { throw null; } } - public string Format { get { throw null; } } - public static System.Security.Cryptography.CngKeyBlobFormat GenericPrivateBlob { get { throw null; } } - public static System.Security.Cryptography.CngKeyBlobFormat GenericPublicBlob { get { throw null; } } - public static System.Security.Cryptography.CngKeyBlobFormat OpaqueTransportBlob { get { throw null; } } - public static System.Security.Cryptography.CngKeyBlobFormat Pkcs8PrivateBlob { get { throw null; } } - public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } - public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngKeyBlobFormat? other) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(System.Security.Cryptography.CngKeyBlobFormat? left, System.Security.Cryptography.CngKeyBlobFormat? right) { throw null; } - public static bool operator !=(System.Security.Cryptography.CngKeyBlobFormat? left, System.Security.Cryptography.CngKeyBlobFormat? right) { throw null; } - public override string ToString() { throw null; } - } - [System.FlagsAttribute] - public enum CngKeyCreationOptions - { - None = 0, - MachineKey = 32, - OverwriteExistingKey = 128, - } - public sealed partial class CngKeyCreationParameters - { - public CngKeyCreationParameters() { } - public System.Security.Cryptography.CngExportPolicies? ExportPolicy { get { throw null; } set { } } - public System.Security.Cryptography.CngKeyCreationOptions KeyCreationOptions { get { throw null; } set { } } - public System.Security.Cryptography.CngKeyUsages? KeyUsage { get { throw null; } set { } } - public System.Security.Cryptography.CngPropertyCollection Parameters { get { throw null; } } - public System.IntPtr ParentWindowHandle { get { throw null; } set { } } - public System.Security.Cryptography.CngProvider Provider { get { throw null; } set { } } - public System.Security.Cryptography.CngUIPolicy? UIPolicy { get { throw null; } set { } } - } - [System.FlagsAttribute] - public enum CngKeyHandleOpenOptions - { - None = 0, - EphemeralKey = 1, - } - [System.FlagsAttribute] - public enum CngKeyOpenOptions - { - None = 0, - UserKey = 0, - MachineKey = 32, - Silent = 64, - } - [System.FlagsAttribute] - public enum CngKeyUsages - { - None = 0, - Decryption = 1, - Signing = 2, - KeyAgreement = 4, - AllUsages = 16777215, - } - public partial struct CngProperty : System.IEquatable - { - private object _dummy; - private int _dummyPrimitive; - public CngProperty(string name, byte[]? value, System.Security.Cryptography.CngPropertyOptions options) { throw null; } - public readonly string Name { get { throw null; } } - public readonly System.Security.Cryptography.CngPropertyOptions Options { get { throw null; } } - public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } - public bool Equals(System.Security.Cryptography.CngProperty other) { throw null; } - public override int GetHashCode() { throw null; } - public byte[]? GetValue() { throw null; } - public static bool operator ==(System.Security.Cryptography.CngProperty left, System.Security.Cryptography.CngProperty right) { throw null; } - public static bool operator !=(System.Security.Cryptography.CngProperty left, System.Security.Cryptography.CngProperty right) { throw null; } - } - public sealed partial class CngPropertyCollection : System.Collections.ObjectModel.Collection - { - public CngPropertyCollection() { } - } - [System.FlagsAttribute] - public enum CngPropertyOptions - { - Persist = -2147483648, - None = 0, - CustomProperty = 1073741824, - } - public sealed partial class CngProvider : System.IEquatable - { - public CngProvider(string provider) { } - public static System.Security.Cryptography.CngProvider MicrosoftPlatformCryptoProvider { get { throw null; } } - public static System.Security.Cryptography.CngProvider MicrosoftSmartCardKeyStorageProvider { get { throw null; } } - public static System.Security.Cryptography.CngProvider MicrosoftSoftwareKeyStorageProvider { get { throw null; } } - public string Provider { get { throw null; } } - public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } - public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngProvider? other) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(System.Security.Cryptography.CngProvider? left, System.Security.Cryptography.CngProvider? right) { throw null; } - public static bool operator !=(System.Security.Cryptography.CngProvider? left, System.Security.Cryptography.CngProvider? right) { throw null; } - public override string ToString() { throw null; } - } - public sealed partial class CngUIPolicy - { - public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel) { } - public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel, string? friendlyName) { } - public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel, string? friendlyName, string? description) { } - public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel, string? friendlyName, string? description, string? useContext) { } - public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel, string? friendlyName, string? description, string? useContext, string? creationTitle) { } - public string? CreationTitle { get { throw null; } } - public string? Description { get { throw null; } } - public string? FriendlyName { get { throw null; } } - public System.Security.Cryptography.CngUIProtectionLevels ProtectionLevel { get { throw null; } } - public string? UseContext { get { throw null; } } - } - [System.FlagsAttribute] - public enum CngUIProtectionLevels - { - None = 0, - ProtectKey = 1, - ForceHighProtection = 2, - } - public sealed partial class DSACng : System.Security.Cryptography.DSA - { - public DSACng() { } - public DSACng(int keySize) { } - public DSACng(System.Security.Cryptography.CngKey key) { } - public System.Security.Cryptography.CngKey Key { get { throw null; } } - public override string? KeyExchangeAlgorithm { get { throw null; } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - public override string SignatureAlgorithm { get { throw null; } } - public override byte[] CreateSignature(byte[] rgbHash) { throw null; } - protected override void Dispose(bool disposing) { } - public override System.Security.Cryptography.DSAParameters ExportParameters(bool includePrivateParameters) { throw null; } - protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public override void ImportParameters(System.Security.Cryptography.DSAParameters parameters) { } - public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) { throw null; } - } - public sealed partial class ECDiffieHellmanCng : System.Security.Cryptography.ECDiffieHellman - { - public ECDiffieHellmanCng() { } - public ECDiffieHellmanCng(int keySize) { } - public ECDiffieHellmanCng(System.Security.Cryptography.CngKey key) { } - public ECDiffieHellmanCng(System.Security.Cryptography.ECCurve curve) { } - public System.Security.Cryptography.CngAlgorithm HashAlgorithm { get { throw null; } set { } } - public byte[]? HmacKey { get { throw null; } set { } } - public System.Security.Cryptography.CngKey Key { get { throw null; } } - public System.Security.Cryptography.ECDiffieHellmanKeyDerivationFunction KeyDerivationFunction { get { throw null; } set { } } - public override int KeySize { get { throw null; } set { } } - public byte[]? Label { get { throw null; } set { } } - public override System.Security.Cryptography.ECDiffieHellmanPublicKey PublicKey { get { throw null; } } - public byte[]? SecretAppend { get { throw null; } set { } } - public byte[]? SecretPrepend { get { throw null; } set { } } - public byte[]? Seed { get { throw null; } set { } } - public bool UseSecretAgreementAsHmacKey { get { throw null; } } - public override byte[] DeriveKeyFromHash(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[]? secretPrepend, byte[]? secretAppend) { throw null; } - public override byte[] DeriveKeyFromHmac(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[]? hmacKey, byte[]? secretPrepend, byte[]? secretAppend) { throw null; } - public byte[] DeriveKeyMaterial(System.Security.Cryptography.CngKey otherPartyPublicKey) { throw null; } - public override byte[] DeriveKeyMaterial(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey) { throw null; } - public override byte[] DeriveKeyTls(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed) { throw null; } - public Microsoft.Win32.SafeHandles.SafeNCryptSecretHandle DeriveSecretAgreementHandle(System.Security.Cryptography.CngKey otherPartyPublicKey) { throw null; } - public Microsoft.Win32.SafeHandles.SafeNCryptSecretHandle DeriveSecretAgreementHandle(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey) { throw null; } - protected override void Dispose(bool disposing) { } - public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters) { throw null; } - public override System.Security.Cryptography.ECParameters ExportParameters(bool includePrivateParameters) { throw null; } - public void FromXmlString(string xml, System.Security.Cryptography.ECKeyXmlFormat format) { } - public override void GenerateKey(System.Security.Cryptography.ECCurve curve) { } - public override void ImportParameters(System.Security.Cryptography.ECParameters parameters) { } - public string ToXmlString(System.Security.Cryptography.ECKeyXmlFormat format) { throw null; } - } - public sealed partial class ECDiffieHellmanCngPublicKey : System.Security.Cryptography.ECDiffieHellmanPublicKey - { - // ECDiffieHellmanPublicKey parameter-less ctor only exist on .NET Framework 4.7+ - private ECDiffieHellmanCngPublicKey() : base(null) { } - public System.Security.Cryptography.CngKeyBlobFormat BlobFormat { get { throw null; } } - protected override void Dispose(bool disposing) { } - public override System.Security.Cryptography.ECParameters ExportExplicitParameters() { throw null; } - public override System.Security.Cryptography.ECParameters ExportParameters() { throw null; } - public static System.Security.Cryptography.ECDiffieHellmanPublicKey FromByteArray(byte[] publicKeyBlob, System.Security.Cryptography.CngKeyBlobFormat format) { throw null; } - public static System.Security.Cryptography.ECDiffieHellmanCngPublicKey FromXmlString(string xml) { throw null; } - public System.Security.Cryptography.CngKey Import() { throw null; } - public override string ToXmlString() { throw null; } - } - public enum ECDiffieHellmanKeyDerivationFunction - { - Hash = 0, - Hmac = 1, - Tls = 2, - } - public sealed partial class ECDsaCng : System.Security.Cryptography.ECDsa - { - public ECDsaCng() { } - public ECDsaCng(int keySize) { } - public ECDsaCng(System.Security.Cryptography.CngKey key) { } - public ECDsaCng(System.Security.Cryptography.ECCurve curve) { } - public System.Security.Cryptography.CngAlgorithm HashAlgorithm { get { throw null; } set { } } - public System.Security.Cryptography.CngKey Key { get { throw null; } } - public override int KeySize { get { throw null; } set { } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - protected override void Dispose(bool disposing) { } - public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters) { throw null; } - public override System.Security.Cryptography.ECParameters ExportParameters(bool includePrivateParameters) { throw null; } - public void FromXmlString(string xml, System.Security.Cryptography.ECKeyXmlFormat format) { } - public override void GenerateKey(System.Security.Cryptography.ECCurve curve) { } - protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public override void ImportParameters(System.Security.Cryptography.ECParameters parameters) { } - public byte[] SignData(byte[] data) { throw null; } - public byte[] SignData(byte[] data, int offset, int count) { throw null; } - public byte[] SignData(System.IO.Stream data) { throw null; } - public override byte[] SignHash(byte[] hash) { throw null; } - public string ToXmlString(System.Security.Cryptography.ECKeyXmlFormat format) { throw null; } - public bool VerifyData(byte[] data, byte[] signature) { throw null; } - public bool VerifyData(byte[] data, int offset, int count, byte[] signature) { throw null; } - public bool VerifyData(System.IO.Stream data, byte[] signature) { throw null; } - public override bool VerifyHash(byte[] hash, byte[] signature) { throw null; } - } - public enum ECKeyXmlFormat - { - Rfc4050 = 0, - } - public sealed partial class RSACng : System.Security.Cryptography.RSA - { - public RSACng() { } - public RSACng(int keySize) { } - public RSACng(System.Security.Cryptography.CngKey key) { } - public System.Security.Cryptography.CngKey Key { get { throw null; } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - public override byte[] Decrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } - protected override void Dispose(bool disposing) { } - public override byte[] Encrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } - public override System.Security.Cryptography.RSAParameters ExportParameters(bool includePrivateParameters) { throw null; } - protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public override void ImportParameters(System.Security.Cryptography.RSAParameters parameters) { } - public override byte[] SignHash(byte[] hash, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } - public override bool VerifyHash(byte[] hash, byte[] signature, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } - } - public sealed partial class TripleDESCng : System.Security.Cryptography.TripleDES - { - public TripleDESCng() { } - public TripleDESCng(string keyName) { } - public TripleDESCng(string keyName, System.Security.Cryptography.CngProvider provider) { } - public TripleDESCng(string keyName, System.Security.Cryptography.CngProvider provider, System.Security.Cryptography.CngKeyOpenOptions openOptions) { } - public override byte[] Key { get { throw null; } set { } } - public override int KeySize { get { throw null; } set { } } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - protected override void Dispose(bool disposing) { } - public override void GenerateIV() { } - public override void GenerateKey() { } - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.csproj b/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.csproj index a473a5b9cbae86..a333acc0151826 100644 --- a/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.csproj +++ b/src/libraries/System.Security.Cryptography.Cng/ref/System.Security.Cryptography.Cng.csproj @@ -4,11 +4,10 @@ enable - + - - \ No newline at end of file + diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/Helpers.cs b/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/Helpers.cs deleted file mode 100644 index 3cbf93ae7510d2..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/Helpers.cs +++ /dev/null @@ -1,178 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; -using System.Globalization; -using System.Security.Cryptography; -using System.Runtime.InteropServices; - -using Microsoft.Win32.SafeHandles; - -using ErrorCode = Interop.NCrypt.ErrorCode; - -namespace Internal.Cryptography -{ - internal static partial class Helpers - { - public static bool UsesIv(this CipherMode cipherMode) - { - return cipherMode != CipherMode.ECB; - } - - public static byte[]? GetCipherIv(this CipherMode cipherMode, byte[]? iv) - { - if (cipherMode.UsesIv()) - { - if (iv == null) - { - throw new CryptographicException(SR.Cryptography_MissingIV); - } - - return iv; - } - - return null; - } - - // - // The C# construct - // - // fixed (byte* p = new byte[0]) - // - // sets "p" to 0 rather than a valid address. Sometimes, we actually want a non-NULL pointer instead. (Some CNG apis actually care whether the buffer pointer is - // NULL or not, even if the accompanying size argument is 0.) - // - // This helper enables the syntax: - // - // fixed (byte* p = new byte[0].MapZeroLengthArrayToNonNullPointer()) - // - // which always sets "p" to a non-NULL pointer for a non-null byte array. - // - public static byte[]? MapZeroLengthArrayToNonNullPointer(this byte[]? src) - { - if (src != null && src.Length == 0) - return new byte[1]; - return src; - } - - public static SafeNCryptProviderHandle OpenStorageProvider(this CngProvider provider) - { - string providerName = provider.Provider; - SafeNCryptProviderHandle providerHandle; - ErrorCode errorCode = Interop.NCrypt.NCryptOpenStorageProvider(out providerHandle, providerName, 0); - if (errorCode != ErrorCode.ERROR_SUCCESS) - throw errorCode.ToCryptographicException(); - return providerHandle; - } - - /// - /// Returns a CNG key property. - /// - /// - /// null - if property not defined on key. - /// throws - for any other type of error. - /// - public static byte[]? GetProperty(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) - { - unsafe - { - int numBytesNeeded; - ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty(ncryptHandle, propertyName, null, 0, out numBytesNeeded, options); - if (errorCode == ErrorCode.NTE_NOT_FOUND) - return null; - if (errorCode != ErrorCode.ERROR_SUCCESS) - throw errorCode.ToCryptographicException(); - - byte[] propertyValue = new byte[numBytesNeeded]; - fixed (byte* pPropertyValue = propertyValue) - { - errorCode = Interop.NCrypt.NCryptGetProperty(ncryptHandle, propertyName, pPropertyValue, propertyValue.Length, out numBytesNeeded, options); - } - if (errorCode == ErrorCode.NTE_NOT_FOUND) - return null; - if (errorCode != ErrorCode.ERROR_SUCCESS) - throw errorCode.ToCryptographicException(); - - Array.Resize(ref propertyValue, numBytesNeeded); - return propertyValue; - } - } - - /// - /// Retrieve a well-known CNG string property. (Note: .NET Framework compat: this helper likes to return special values rather than throw exceptions for missing - /// or ill-formatted property values. Only use it for well-known properties that are unlikely to be ill-formatted.) - /// - public static string? GetPropertyAsString(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) - { - byte[]? value = ncryptHandle.GetProperty(propertyName, options); - if (value == null) - return null; // .NET Framework compat: return null if key not present. - if (value.Length == 0) - return string.Empty; // .NET Framework compat: return empty if property value is 0-length. - unsafe - { - fixed (byte* pValue = &value[0]) - { - string? valueAsString = Marshal.PtrToStringUni((IntPtr)pValue); - return valueAsString; - } - } - } - - /// - /// Retrieve a well-known CNG dword property. (Note: .NET Framework compat: this helper likes to return special values rather than throw exceptions for missing - /// or ill-formatted property values. Only use it for well-known properties that are unlikely to be ill-formatted.) - /// - public static int GetPropertyAsDword(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) - { - byte[]? value = ncryptHandle.GetProperty(propertyName, options); - if (value == null) - return 0; // .NET Framework compat: return 0 if key not present. - return BitConverter.ToInt32(value, 0); - } - - /// - /// Retrieve a well-known CNG pointer property. (Note: .NET Framework compat: this helper likes to return special values rather than throw exceptions for missing - /// or ill-formatted property values. Only use it for well-known properties that are unlikely to be ill-formatted.) - /// - public static IntPtr GetPropertyAsIntPtr(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) - { - unsafe - { - IntPtr value; - ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty(ncryptHandle, propertyName, &value, IntPtr.Size, out _, options); - if (errorCode == ErrorCode.NTE_NOT_FOUND) - return IntPtr.Zero; - if (errorCode != ErrorCode.ERROR_SUCCESS) - throw errorCode.ToCryptographicException(); - return value; - } - } - - /// - /// Modify a CNG key's export policy. - /// - public static void SetExportPolicy(this SafeNCryptKeyHandle keyHandle, CngExportPolicies exportPolicy) - { - unsafe - { - ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.ExportPolicy, &exportPolicy, sizeof(CngExportPolicies), CngPropertyOptions.Persist); - if (errorCode != ErrorCode.ERROR_SUCCESS) - throw errorCode.ToCryptographicException(); - } - } - - public static int BitSizeToByteSize(this int bits) - { - return (bits + 7) / 8; - } - - public static byte[] GenerateRandom(int count) - { - byte[] buffer = new byte[count]; - RandomNumberGenerator.Fill(buffer); - return buffer; - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/KeyPropertyName.cs b/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/KeyPropertyName.cs deleted file mode 100644 index 03986a9010343c..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/KeyPropertyName.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; - -namespace Internal.Cryptography -{ - /// - /// Well known names of key properties - /// - internal static class KeyPropertyName - { - internal const string Algorithm = "Algorithm Name"; // NCRYPT_ALGORITHM_PROPERTY - internal const string AlgorithmGroup = "Algorithm Group"; // NCRYPT_ALGORITHM_GROUP_PROPERTY - internal const string ECCCurveName = "ECCCurveName"; // NCRYPT_ECC_CURVE_NAME - internal const string ECCParameters = "ECCParameters"; // BCRYPT_ECC_PARAMETERS - internal const string ExportPolicy = "Export Policy"; // NCRYPT_EXPORT_POLICY_PROPERTY - internal const string KeyType = "Key Type"; // NCRYPT_KEY_TYPE_PROPERTY - internal const string KeyUsage = "Key Usage"; // NCRYPT_KEY_USAGE_PROPERTY - internal const string Length = "Length"; // NCRYPT_LENGTH_PROPERTY - internal const string Name = "Name"; // NCRYPT_NAME_PROPERTY - internal const string ParentWindowHandle = "HWND Handle"; // NCRYPT_WINDOW_HANDLE_PROPERTY - internal const string PublicKeyLength = "PublicKeyLength"; // NCRYPT_PUBLIC_KEY_LENGTH (Win10+) - internal const string ProviderHandle = "Provider Handle"; // NCRYPT_PROVIDER_HANDLE_PROPERTY - internal const string UIPolicy = "UI Policy"; // NCRYPT_UI_POLICY_PROPERTY - internal const string UniqueName = "Unique Name"; // NCRYPT_UNIQUE_NAME_PROPERTY - internal const string UseContext = "Use Context"; // NCRYPT_USE_CONTEXT_PROPERTY - - // - // Properties defined by the CLR - // - - /// - /// Is the key a CLR created ephemeral key, it will contain a single byte with value 1 if the - /// key was created by the CLR as an ephemeral key. - /// - internal const string ClrIsEphemeral = "CLR IsEphemeral"; - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/SymmetricImportExportExtensions.cs b/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/SymmetricImportExportExtensions.cs deleted file mode 100644 index ff988a0da5e078..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/SymmetricImportExportExtensions.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; -using System.Text; -using System.Diagnostics; -using System.Globalization; -using System.Security.Cryptography; - -namespace Internal.Cryptography -{ - internal static class SymmetricImportExportExtensions - { - - /// - /// Note! This can and likely will throw if the algorithm was given a hardware-based key. - /// - public static byte[] GetSymmetricKeyDataIfExportable(this CngKey cngKey, string algorithm) - { - byte[] keyBlob = cngKey.Export(s_cipherKeyBlobFormat); - using (MemoryStream ms = new MemoryStream(keyBlob)) - { - using (BinaryReader br = new BinaryReader(ms, Encoding.Unicode)) - { - // Read NCRYPT_KEY_BLOB_HEADER - int cbSize = br.ReadInt32(); // NCRYPT_KEY_BLOB_HEADER.cbSize - if (cbSize != SizeOf_NCRYPT_KEY_BLOB_HEADER_SIZE) - throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); - - int ncryptMagic = br.ReadInt32(); // NCRYPT_KEY_BLOB_HEADER.dwMagic - if (ncryptMagic != Interop.NCrypt.NCRYPT_CIPHER_KEY_BLOB_MAGIC) - throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); - - int cbAlgName = br.ReadInt32(); // NCRYPT_KEY_BLOB_HEADER.cbAlgName - - br.ReadInt32(); // NCRYPT_KEY_BLOB_HEADER.cbKey - - string algorithmName = new string(br.ReadChars((cbAlgName / 2) - 1)); - if (algorithmName != algorithm) - throw new CryptographicException(SR.Format(SR.Cryptography_CngKeyWrongAlgorithm, algorithmName, algorithm)); - - char nullTerminator = br.ReadChar(); - if (nullTerminator != 0) - throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); - - // Read BCRYPT_KEY_DATA_BLOB_HEADER - int bcryptMagic = br.ReadInt32(); // BCRYPT_KEY_DATA_BLOB_HEADER.dwMagic - if (bcryptMagic != Interop.BCrypt.BCRYPT_KEY_DATA_BLOB_MAGIC) - throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); - - int dwVersion = br.ReadInt32(); // BCRYPT_KEY_DATA_BLOB_HEADER.dwVersion - if (dwVersion != Interop.BCrypt.BCRYPT_KEY_DATA_BLOB_VERSION1) - throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); - - int keyLength = br.ReadInt32(); // BCRYPT_KEY_DATA_BLOB_HEADER.cbKeyData - byte[] key = br.ReadBytes(keyLength); - return key; - } - } - } - - private const int SizeOf_NCRYPT_KEY_BLOB_HEADER_SIZE = sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int); - - private static readonly CngKeyBlobFormat s_cipherKeyBlobFormat = new CngKeyBlobFormat(Interop.NCrypt.NCRYPT_CIPHER_KEY_BLOB); - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography.Cng/src/Resources/Strings.resx deleted file mode 100644 index 06bd0851e990e9..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/Resources/Strings.resx +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Non-negative number required. - - - The destination is too small to hold the encoded value. - - - The method cannot be called with an invalid or closed SafeHandle. - - - Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. - - - The OID value was invalid. - - - Value was invalid. - - - Buffer cannot be null. - - - Positive number required. - - - Algorithm '{0}' is not supported on this platform. - - - The KDF for algorithm '{0}' requires a char-based password input. - - - The keys from both parties must be the same size to generate a secret agreement. - - - Keys used with the ECDiffieHellmanCng algorithm must have an algorithm group of ECDiffieHellman. - - - The TLS key derivation function requires both the label and seed properties to be set. - - - Keys used with the DSACng algorithm must have an algorithm group of DSA. - - - Keys used with the ECDsaCng algorithm must have an algorithm group of ECDsa. - - - Keys used with the RSACng algorithm must have an algorithm group of RSA. - - - The specified feedback size '{0}' for CipherMode '{1}' is not supported. - - - This key is for algorithm '{0}'. Expected '{1}'. - - - ASN1 corrupted data. - - - The message exceeds the maximum allowable length for the chosen options ({0}). - - - Specified cipher mode is not valid for this algorithm. - - - The specified DSA parameters are not valid; P, Q, G and Y are all required. - - - The specified DSA parameters are not valid; P, G and Y must be the same length (the key size). - - - The specified DSA parameters are not valid; Q and X (if present) must be the same length. - - - The specified DSA parameters are not valid; J (if present) must be shorter than P. - - - The specified DSA parameters are not valid; Seed, if present, must be 20 bytes long for keys shorter than 1024 bits. - - - The specified DSA parameters are not valid; Q must be 20 bytes long for keys shorter than 1024 bits. - - - The specified DSA parameters are not valid; Q's length must be one of 20, 32 or 64 bytes. - - - The specified curve '{0}' or its parameters are not valid for this platform. - - - The specified Oid ({0}) is not valid. The Oid.FriendlyName or Oid.Value property must be set. - - - Specified initialization vector (IV) does not match the block size for this algorithm. - - - Specified key is not a valid size for this algorithm. - - - Padding is invalid and cannot be removed. - - - The specified RSA parameters are not valid. Exponent and Modulus are required. If D is present, it must have the same length as Modulus. If D is present, P, Q, DP, DQ, and InverseQ are required and must have half the length of Modulus, rounded up, otherwise they must be omitted. - - - Key Blob not in expected format. - - - The key is too small for the requested operation. - - - The CNG key handle being opened was detected to be ephemeral, but the EphemeralKey open option was not specified. - - - Cannot open an invalid handle. - - - The cipher mode specified requires that an initialization vector (IV) be used. - - - TransformBlock may only process bytes in block sized increments. - - - Key is not a valid private key. - - - Key is not a valid public or private key. - - - Error occurred while decoding OAEP padding. - - - The input data is not a complete block. - - - The length of the data to decrypt is not valid for the size of this key. - - - The EncryptedPrivateKeyInfo structure was decoded but was not successfully interpreted, the password may be incorrect. - - - The provided hash value is not the expected size for the specified hash algorithm. - - - The specified PaddingMode is not supported. - - - CNG provider unexpectedly terminated encryption or decryption prematurely. - - - The algorithm identified by '{0}' is unknown, not valid for the requested usage, or was not handled. - - - '{0}' is not a known hash algorithm. - - - Unknown padding mode used. - - - Specified key is a known weak key for this algorithm and cannot be used. - - - Windows Cryptography Next Generation (CNG) is not supported on this platform. - - - Only named curves are supported on this platform. - - - Object contains only the public half of a key pair. A private key must also be provided. - - - The specified Characteristic2 curve parameters are not valid. Polynomial, A, B, G.X, G.Y, and Order are required. A, B, G.X, G.Y must be the same length, and the same length as Q.X, Q.Y and D if those are specified. Seed, Cofactor and Hash are optional. Other parameters are not allowed. - - - Destination is too short. - - - The current platform does not support the specified feedback size. - - diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System.Security.Cryptography.Cng.csproj b/src/libraries/System.Security.Cryptography.Cng/src/System.Security.Cryptography.Cng.csproj index fa3b70f4d35abe..1fe031a388f591 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System.Security.Cryptography.Cng.csproj +++ b/src/libraries/System.Security.Cryptography.Cng/src/System.Security.Cryptography.Cng.csproj @@ -1,380 +1,10 @@ - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent) - true - enable + $(NetCoreAppCurrent) + true - - - SR.PlatformNotSupported_CryptographyCng - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml - - - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml.cs - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml - - - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.manual.cs - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml - - - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml - - - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml.cs - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml - - - Common\System\Security\Cryptography\Asn1\PBEParameter.xml - - - Common\System\Security\Cryptography\Asn1\PBEParameter.xml.cs - Common\System\Security\Cryptography\Asn1\PBEParameter.xml - - - Common\System\Security\Cryptography\Asn1\PBES2Params.xml - - - Common\System\Security\Cryptography\Asn1\PBES2Params.xml.cs - Common\System\Security\Cryptography\Asn1\PBES2Params.xml - - - Common\System\Security\Cryptography\Asn1\Pbkdf2Params.xml - - - Common\System\Security\Cryptography\Asn1\Pbkdf2Params.xml.cs - Common\System\Security\Cryptography\Asn1\Pbkdf2Params.xml - - - Common\System\Security\Cryptography\Asn1\Pbkdf2SaltChoice.xml - - - Common\System\Security\Cryptography\Asn1\Pbkdf2SaltChoice.xml.cs - Common\System\Security\Cryptography\Asn1\Pbkdf2SaltChoice.xml - - - Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml - - - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml.cs - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml - - - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.manual.cs - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml - - - Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\ECDomainParameters.xml - - - Common\System\Security\Cryptography\Asn1\ECDomainParameters.xml.cs - Common\System\Security\Cryptography\Asn1\ECDomainParameters.xml - - - Common\System\Security\Cryptography\Asn1\SpecifiedECDomain.xml - - - Common\System\Security\Cryptography\Asn1\SpecifiedECDomain.xml.cs - Common\System\Security\Cryptography\Asn1\SpecifiedECDomain.xml - - - Common\System\Security\Cryptography\Asn1\CurveAsn.xml - - - Common\System\Security\Cryptography\Asn1\CurveAsn.xml.cs - Common\System\Security\Cryptography\Asn1\CurveAsn.xml - - - Common\System\Security\Cryptography\Asn1\FieldID.xml - - - Common\System\Security\Cryptography\Asn1\FieldID.xml.cs - Common\System\Security\Cryptography\Asn1\FieldID.xml - - - Common\System\Security\Cryptography\Asn1\FieldID.xml - - - Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml.cs - Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngPkcs8.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngPkcs8.cs deleted file mode 100644 index 9b93cf8151023c..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngPkcs8.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Buffers; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Security.Cryptography.Asn1; - -namespace System.Security.Cryptography -{ - internal static partial class CngPkcs8 - { - internal struct Pkcs8Response - { - internal CngKey Key; - - internal string GetAlgorithmGroup() - { - return Key.AlgorithmGroup!.AlgorithmGroup; - } - - internal void FreeKey() - { - Key.Dispose(); - } - } - - private static Pkcs8Response ImportPkcs8(ReadOnlySpan keyBlob) - { - CngKey key = CngKey.Import(keyBlob, CngKeyBlobFormat.Pkcs8PrivateBlob); - key.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport; - - return new Pkcs8Response - { - Key = key, - }; - } - - private static Pkcs8Response ImportPkcs8( - ReadOnlySpan keyBlob, - ReadOnlySpan password) - { - CngKey key = CngKey.ImportEncryptedPkcs8(keyBlob, password); - key.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport; - - return new Pkcs8Response - { - Key = key, - }; - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/DSACng.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/DSACng.cs deleted file mode 100644 index b01714761966d1..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/DSACng.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Internal.Cryptography; - -namespace System.Security.Cryptography -{ - public sealed partial class DSACng : DSA - { - private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(DSACng)); - - /// - /// Creates a new DSACng object that will use the specified key. The key's - /// must be Dsa. This constructor - /// creates a copy of the key. Hence, the caller can safely dispose of the - /// passed in key and continue using the DSACng object. - /// - /// Key to use for DSA operations - /// if is not an DSA key - /// if is null. - public DSACng(CngKey key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - - if (key.AlgorithmGroup != CngAlgorithmGroup.Dsa) - throw new ArgumentException(SR.Cryptography_ArgDSARequiresDSAKey, nameof(key)); - - Key = CngAlgorithmCore.Duplicate(key); - } - - protected override void Dispose(bool disposing) - { - _core.Dispose(); - } - - private void ThrowIfDisposed() - { - _core.ThrowIfDisposed(); - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.Derive.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.Derive.cs deleted file mode 100644 index deca9cfd932eeb..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.Derive.cs +++ /dev/null @@ -1,146 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using Microsoft.Win32.SafeHandles; - -namespace System.Security.Cryptography -{ - public sealed partial class ECDiffieHellmanCng : ECDiffieHellman - { - public override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey) - { - if (otherPartyPublicKey == null) - throw new ArgumentNullException(nameof(otherPartyPublicKey)); - - if (otherPartyPublicKey is ECDiffieHellmanCngPublicKey otherKey) - { - using (CngKey import = otherKey.Import()) - { - return DeriveKeyMaterial(import); - } - } - - // This deviates from the .NET Framework behavior. .NET Framework can't handle unknown public - // key types, but on .NET Core there are automatically two: the public class produced by - // this class' PublicKey member, and the private class produced by ECDiffieHellman.Create().PublicKey - // - // So let's just work. - ECParameters otherPartyParameters = otherPartyPublicKey.ExportParameters(); - - using (ECDiffieHellmanCng otherPartyCng = new ECDiffieHellmanCng()) - { - otherPartyCng.ImportParameters(otherPartyParameters); - - using (otherKey = (ECDiffieHellmanCngPublicKey)otherPartyCng.PublicKey) - using (CngKey importedKey = otherKey.Import()) - { - return DeriveKeyMaterial(importedKey); - } - } - } - - public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey) - { - if (otherPartyPublicKey == null) - throw new ArgumentNullException(nameof(otherPartyPublicKey)); - if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) - throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(otherPartyPublicKey)); - if (otherPartyPublicKey.KeySize != KeySize) - throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey)); - - // Setting the flag to UseSecretAsHmacKey even when the KDF isn't HMAC, because that's what .NET Framework does. - Interop.NCrypt.SecretAgreementFlags flags = - UseSecretAgreementAsHmacKey - ? Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey - : Interop.NCrypt.SecretAgreementFlags.None; - - using (SafeNCryptSecretHandle handle = DeriveSecretAgreementHandle(otherPartyPublicKey)) - { - switch (KeyDerivationFunction) - { - case ECDiffieHellmanKeyDerivationFunction.Hash: - return Interop.NCrypt.DeriveKeyMaterialHash( - handle, - HashAlgorithm.Algorithm, - _secretPrepend, - _secretAppend, - flags); - case ECDiffieHellmanKeyDerivationFunction.Hmac: - return Interop.NCrypt.DeriveKeyMaterialHmac( - handle, - HashAlgorithm.Algorithm, - _hmacKey, - _secretPrepend, - _secretAppend, - flags); - case ECDiffieHellmanKeyDerivationFunction.Tls: - if (_label == null || _seed == null) - { - throw new InvalidOperationException(SR.Cryptography_TlsRequiresLabelAndSeed); - } - - return Interop.NCrypt.DeriveKeyMaterialTls( - handle, - _label, - _seed, - flags); - default: - Debug.Fail($"Unknown KDF ({KeyDerivationFunction})"); - // Match .NET Framework behavior - goto case ECDiffieHellmanKeyDerivationFunction.Tls; - } - } - } - - /// - /// Get a handle to the secret agreement generated between two parties - /// - public SafeNCryptSecretHandle DeriveSecretAgreementHandle(ECDiffieHellmanPublicKey otherPartyPublicKey) - { - if (otherPartyPublicKey == null) - throw new ArgumentNullException(nameof(otherPartyPublicKey)); - - if (otherPartyPublicKey is ECDiffieHellmanCngPublicKey otherKey) - { - using (CngKey importedKey = otherKey.Import()) - { - return DeriveSecretAgreementHandle(importedKey); - } - } - - ECParameters otherPartyParameters = otherPartyPublicKey.ExportParameters(); - - using (ECDiffieHellmanCng otherPartyCng = new ECDiffieHellmanCng()) - { - otherPartyCng.ImportParameters(otherPartyParameters); - - using (otherKey = (ECDiffieHellmanCngPublicKey)otherPartyCng.PublicKey) - using (CngKey importedKey = otherKey.Import()) - { - return DeriveSecretAgreementHandle(importedKey); - } - } - } - - /// - /// Get a handle to the secret agreement between two parties - /// - public SafeNCryptSecretHandle DeriveSecretAgreementHandle(CngKey otherPartyPublicKey) - { - if (otherPartyPublicKey == null) - throw new ArgumentNullException(nameof(otherPartyPublicKey)); - if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) - throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(otherPartyPublicKey)); - if (otherPartyPublicKey.KeySize != KeySize) - throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey)); - - // This looks strange, but the Handle property returns a duplicate so we need to dispose of it when we're done - using (SafeNCryptKeyHandle localHandle = Key.Handle) - using (SafeNCryptKeyHandle otherPartyHandle = otherPartyPublicKey.Handle) - { - return Interop.NCrypt.DeriveSecretAgreement(localHandle, otherPartyHandle); - } - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.Key.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.Key.cs deleted file mode 100644 index baf5046f242e37..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.Key.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using Microsoft.Win32.SafeHandles; - -namespace System.Security.Cryptography -{ - public sealed partial class ECDiffieHellmanCng : ECDiffieHellman - { - /// - /// Public key used to generate key material with the second party - /// - public override ECDiffieHellmanPublicKey PublicKey - { - get - { - return ECDiffieHellmanCngPublicKey.FromKey(Key); - } - } - - /// - /// Gets the key that will be used by the ECDH object for any cryptographic operation that it uses. - /// This key object will be disposed if the key is reset, for instance by changing the KeySize - /// property, using ImportParamers to create a new key, or by Disposing of the parent ECDH object. - /// Therefore, you should make sure that the key object is no longer used in these scenarios. This - /// object will not be the same object as the CngKey passed to the ECDHCng constructor if that - /// constructor was used, however it will point at the same CNG key. - /// - public CngKey Key - { - get - { - return GetKey(); - } - - private set - { - if (value == null) - throw new ArgumentNullException(nameof(value)); - if (value.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) - throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(value)); - - _core.SetKey(value); - - // LegalKeySizes stores the values for either the current named curve or for the three - // curves that use size instead of name - ForceSetKeySize(value.KeySize); - } - } - - public override void GenerateKey(ECCurve curve) - { - curve.Validate(); - _core.DisposeKey(); - - if (curve.IsNamed) - { - if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) - throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value)); - - // Map curve name to algorithm to support pre-Win10 curves - CngAlgorithm alg = CngKey.EcdhCurveNameToAlgorithm(curve.Oid.FriendlyName); - if (CngKey.IsECNamedCurve(alg.Algorithm)) - { - CngKey key = _core.GetOrGenerateKey(curve); - ForceSetKeySize(key.KeySize); - } - else - { - int keySize; - // Get the proper KeySize from algorithm name - if (alg == CngAlgorithm.ECDiffieHellmanP256) - keySize = 256; - else if (alg == CngAlgorithm.ECDiffieHellmanP384) - keySize = 384; - else if (alg == CngAlgorithm.ECDiffieHellmanP521) - keySize = 521; - else - { - Debug.Fail($"Unknown algorithm {alg}"); - throw new ArgumentException(SR.Cryptography_InvalidKeySize); - } - _core.GetOrGenerateKey(keySize, alg); - ForceSetKeySize(keySize); - } - } - else if (curve.IsExplicit) - { - CngKey key = _core.GetOrGenerateKey(curve); - ForceSetKeySize(key.KeySize); - } - else - { - throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); - } - } - - private CngKey GetKey() - { - CngKey key; - - if (_core.IsKeyGeneratedNamedCurve()) - { - // Curve was previously created, so use that - key = _core.GetOrGenerateKey(null); - } - else - { - CngAlgorithm algorithm; - - // Map the current key size to a CNG algorithm name - int keySize = KeySize; - switch (keySize) - { - case 256: - algorithm = CngAlgorithm.ECDiffieHellmanP256; - break; - case 384: - algorithm = CngAlgorithm.ECDiffieHellmanP384; - break; - case 521: - algorithm = CngAlgorithm.ECDiffieHellmanP521; - break; - default: - Debug.Fail("Should not have invalid key size"); - throw new ArgumentException(SR.Cryptography_InvalidKeySize); - } - key = _core.GetOrGenerateKey(keySize, algorithm); - } - - return key; - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.cs deleted file mode 100644 index c6baf43ef1aec6..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.cs +++ /dev/null @@ -1,209 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Internal.Cryptography; - -namespace System.Security.Cryptography -{ - /// - /// Key derivation functions used to transform the raw secret agreement into key material - /// - public enum ECDiffieHellmanKeyDerivationFunction - { - Hash, - Hmac, - Tls - } - - /// - /// Wrapper for CNG's implementation of elliptic curve Diffie-Hellman key exchange - /// - public sealed partial class ECDiffieHellmanCng : ECDiffieHellman - { - private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(ECDiffieHellmanCng)) { DefaultKeyType = CngAlgorithm.ECDiffieHellman }; - private CngAlgorithm _hashAlgorithm = CngAlgorithm.Sha256; - private ECDiffieHellmanKeyDerivationFunction _kdf = ECDiffieHellmanKeyDerivationFunction.Hash; - private byte[]? _hmacKey; - private byte[]? _label; - private byte[]? _secretAppend; - private byte[]? _secretPrepend; - private byte[]? _seed; - - public ECDiffieHellmanCng(CngKey key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - - if (key.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) - throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(key)); - - Key = CngAlgorithmCore.Duplicate(key); - } - - /// - /// Hash algorithm used with the Hash and HMAC KDFs - /// - public CngAlgorithm HashAlgorithm - { - get - { - return _hashAlgorithm; - } - - set - { - if (_hashAlgorithm == null) - { - throw new ArgumentNullException(nameof(value)); - } - - _hashAlgorithm = value; - } - } - - /// - /// KDF used to transform the secret agreement into key material - /// - public ECDiffieHellmanKeyDerivationFunction KeyDerivationFunction - { - get - { - return _kdf; - } - - set - { - if (value < ECDiffieHellmanKeyDerivationFunction.Hash || value > ECDiffieHellmanKeyDerivationFunction.Tls) - { - throw new ArgumentOutOfRangeException(nameof(value)); - } - - _kdf = value; - } - } - - /// - /// Key used with the HMAC KDF - /// - public byte[]? HmacKey - { - get { return _hmacKey; } - set { _hmacKey = value; } - } - - /// - /// Label bytes used for the TLS KDF - /// - public byte[]? Label - { - get { return _label; } - set { _label = value; } - } - - /// - /// Bytes to append to the raw secret agreement before processing by the KDF - /// - public byte[]? SecretAppend - { - get { return _secretAppend; } - set { _secretAppend = value; } - } - - /// - /// Bytes to prepend to the raw secret agreement before processing by the KDF - /// - public byte[]? SecretPrepend - { - get { return _secretPrepend; } - set { _secretPrepend = value; } - } - - /// - /// Seed bytes used for the TLS KDF - /// - public byte[]? Seed - { - get { return _seed; } - set { _seed = value; } - } - - /// - /// Use the secret agreement as the HMAC key rather than supplying a seperate one - /// - public bool UseSecretAgreementAsHmacKey - { - get { return HmacKey == null; } - } - - protected override void Dispose(bool disposing) - { - _core.Dispose(); - } - - private void ThrowIfDisposed() - { - _core.ThrowIfDisposed(); - } - - private void DisposeKey() - { - _core.DisposeKey(); - } - - internal string? GetCurveName(out string? oidValue) - { - return Key.GetCurveName(out oidValue); - } - - private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters) - { - Key = ECCng.ImportFullKeyBlob(ecfullKeyBlob, includePrivateParameters); - } - - private void ImportKeyBlob(byte[] ecfullKeyBlob, string curveName, bool includePrivateParameters) - { - Key = ECCng.ImportKeyBlob(ecfullKeyBlob, curveName, includePrivateParameters); - } - - private byte[] ExportKeyBlob(bool includePrivateParameters) - { - return ECCng.ExportKeyBlob(Key, includePrivateParameters); - } - - private byte[] ExportFullKeyBlob(bool includePrivateParameters) - { - return ECCng.ExportFullKeyBlob(Key, includePrivateParameters); - } - - private void AcceptImport(CngPkcs8.Pkcs8Response response) - { - Key = response.Key; - } - - public override bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritten) - { - return Key.TryExportKeyBlob( - Interop.NCrypt.NCRYPT_PKCS8_PRIVATE_KEY_BLOB, - destination, - out bytesWritten); - } - - private byte[] ExportEncryptedPkcs8(ReadOnlySpan pkcs8Password, int kdfCount) - { - return Key.ExportPkcs8KeyBlob(pkcs8Password, kdfCount); - } - - private bool TryExportEncryptedPkcs8( - ReadOnlySpan pkcs8Password, - int kdfCount, - Span destination, - out int bytesWritten) - { - return Key.TryExportPkcs8KeyBlob( - pkcs8Password, - kdfCount, - destination, - out bytesWritten); - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs deleted file mode 100644 index 0ae53b69204131..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs +++ /dev/null @@ -1,153 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Security.Cryptography -{ - /// - /// Public key used to do key exchange with the ECDiffieHellmanCng algorithm - /// - public sealed partial class ECDiffieHellmanCngPublicKey : ECDiffieHellmanPublicKey - { - private readonly CngKeyBlobFormat _format; - private readonly string? _curveName; - private bool _disposed; - - /// - /// Wrap a CNG key - /// - internal ECDiffieHellmanCngPublicKey(byte[] keyBlob, string? curveName, CngKeyBlobFormat format) : base(keyBlob) - { - _format = format; - // Can be null for P256, P384, P521, or an explicit blob - _curveName = curveName; - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - _disposed = true; - } - - base.Dispose(disposing); - } - - public override string ToXmlString() - { - throw new PlatformNotSupportedException(); - } - - public static ECDiffieHellmanCngPublicKey FromXmlString(string xml) - { - throw new PlatformNotSupportedException(); - } - - /// - /// Format the key blob is expressed in - /// - public CngKeyBlobFormat BlobFormat - { - get - { - return _format; - } - } - - /// - /// Hydrate a public key from a blob - /// - public static ECDiffieHellmanPublicKey FromByteArray(byte[] publicKeyBlob, CngKeyBlobFormat format) - { - if (publicKeyBlob == null) - throw new ArgumentNullException(nameof(publicKeyBlob)); - if (format == null) - throw new ArgumentNullException(nameof(format)); - - // Verify that the key can import successfully, because we did in the past. - using (CngKey imported = CngKey.Import(publicKeyBlob, format)) - { - if (imported.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) - { - throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey); - } - - return new ECDiffieHellmanCngPublicKey(publicKeyBlob, null, format); - } - } - - internal static ECDiffieHellmanCngPublicKey FromKey(CngKey key) - { - CngKeyBlobFormat format; - string? curveName; - byte[] blob = ECCng.ExportKeyBlob(key, false, out format, out curveName); - return new ECDiffieHellmanCngPublicKey(blob, curveName, format); - } - - /// - /// Import the public key into CNG - /// - /// - public CngKey Import() - { - if (_disposed) - { - throw new ObjectDisposedException(nameof(ECDiffieHellmanCngPublicKey)); - } - - return CngKey.Import(ToByteArray(), _curveName, BlobFormat); - } - - /// - /// Exports the key and explicit curve parameters used by the ECC object into an object. - /// - /// - /// if there was an issue obtaining the curve values. - /// - /// - /// if explicit export is not supported by this platform. Windows 10 or higher is required. - /// - /// The key and explicit curve parameters used by the ECC object. - public override ECParameters ExportExplicitParameters() - { - using (CngKey key = Import()) - { - ECParameters ecparams = default; - byte[] blob = ECCng.ExportFullKeyBlob(key, includePrivateParameters: false); - ECCng.ExportPrimeCurveParameters(ref ecparams, blob, includePrivateParameters: false); - return ecparams; - } - } - - /// - /// Exports the key used by the ECC object into an object. - /// If the key was created as a named curve, the Curve property will contain named curve parameters - /// otherwise it will contain explicit parameters. - /// - /// - /// if there was an issue obtaining the curve values. - /// - /// The key and named curve parameters used by the ECC object. - public override ECParameters ExportParameters() - { - using (CngKey key = Import()) - { - ECParameters ecparams = default; - string? curveName = key.GetCurveName(out _); - - if (string.IsNullOrEmpty(curveName)) - { - byte[] fullKeyBlob = ECCng.ExportFullKeyBlob(key, includePrivateParameters: false); - ECCng.ExportPrimeCurveParameters(ref ecparams, fullKeyBlob, includePrivateParameters: false); - } - else - { - byte[] keyBlob = ECCng.ExportKeyBlob(key, includePrivateParameters: false); - ECCng.ExportNamedCurveParameters(ref ecparams, keyBlob, includePrivateParameters: false); - ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName); - } - - return ecparams; - } - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDsaCng.Key.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDsaCng.Key.cs deleted file mode 100644 index aabaf167957532..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDsaCng.Key.cs +++ /dev/null @@ -1,123 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Security.Cryptography -{ - using Microsoft.Win32.SafeHandles; - using System.Diagnostics; - - public sealed partial class ECDsaCng : ECDsa - { - /// - /// Gets the key that will be used by the ECDsa object for any cryptographic operation that it uses. - /// This key object will be disposed if the key is reset, for instance by changing the KeySize - /// property, using ImportParamers to create a new key, or by Disposing of the parent ECDsa object. - /// Therefore, you should make sure that the key object is no longer used in these scenarios. This - /// object will not be the same object as the CngKey passed to the ECDsaCng constructor if that - /// constructor was used, however it will point at the same CNG key. - /// - public CngKey Key - { - get - { - return GetKey(); - } - - private set - { - if (value == null) - throw new ArgumentNullException(nameof(value)); - - if (!IsEccAlgorithmGroup(value.AlgorithmGroup)) - throw new ArgumentException(SR.Cryptography_ArgECDsaRequiresECDsaKey, nameof(value)); - _core.SetKey(value); - - // LegalKeySizes stores the values for either the current named curve or for the three - // curves that use size instead of name - ForceSetKeySize(value.KeySize); - } - } - - public override void GenerateKey(ECCurve curve) - { - curve.Validate(); - _core.DisposeKey(); - - if (curve.IsNamed) - { - if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) - throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value)); - - // Map curve name to algorithm to support pre-Win10 curves - CngAlgorithm alg = CngKey.EcdsaCurveNameToAlgorithm(curve.Oid.FriendlyName); - if (CngKey.IsECNamedCurve(alg.Algorithm)) - { - CngKey key = _core.GetOrGenerateKey(curve); - ForceSetKeySize(key.KeySize); - } - else - { - int keySize; - // Get the proper KeySize from algorithm name - if (alg == CngAlgorithm.ECDsaP256) - keySize = 256; - else if (alg == CngAlgorithm.ECDsaP384) - keySize = 384; - else if (alg == CngAlgorithm.ECDsaP521) - keySize = 521; - else - { - Debug.Fail($"Unknown algorithm {alg}"); - throw new ArgumentException(SR.Cryptography_InvalidKeySize); - } - _core.GetOrGenerateKey(keySize, alg); - ForceSetKeySize(keySize); - } - } - else if (curve.IsExplicit) - { - CngKey key = _core.GetOrGenerateKey(curve); - ForceSetKeySize(key.KeySize); - } - else - { - throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); - } - } - - private CngKey GetKey() - { - CngKey key; - - if (_core.IsKeyGeneratedNamedCurve()) - { - // Curve was previously created, so use that - key = _core.GetOrGenerateKey(null); - } - else - { - CngAlgorithm algorithm; - - // Map the current key size to a CNG algorithm name - int keySize = KeySize; - switch (keySize) - { - case 256: algorithm = CngAlgorithm.ECDsaP256; break; - case 384: algorithm = CngAlgorithm.ECDsaP384; break; - case 521: algorithm = CngAlgorithm.ECDsaP521; break; - default: - Debug.Fail("Should not have invalid key size"); - throw new ArgumentException(SR.Cryptography_InvalidKeySize); - } - key = _core.GetOrGenerateKey(keySize, algorithm); - } - - return key; - } - - private SafeNCryptKeyHandle GetDuplicatedKeyHandle() - { - return Key.Handle; - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDsaCng.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDsaCng.cs deleted file mode 100644 index 19dd910a4cc885..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDsaCng.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.IO; -using Internal.Cryptography; - -namespace System.Security.Cryptography -{ - public sealed partial class ECDsaCng : ECDsa - { - private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(ECDsaCng)); - private CngAlgorithm _hashAlgorithm = CngAlgorithm.Sha256; - - /// - /// Hash algorithm to use when generating a signature over arbitrary data - /// - public CngAlgorithm HashAlgorithm - { - get - { - return _hashAlgorithm; - } - set - { - _hashAlgorithm = value ?? throw new ArgumentNullException(nameof(value)); - } - } - - /// - /// Creates a new ECDsaCng object that will use the specified key. The key's - /// must be ECDsa. This constructor - /// creates a copy of the key. Hence, the caller can safely dispose of the - /// passed in key and continue using the ECDsaCng object. - /// - /// Key to use for ECDsa operations - /// if is not an ECDsa key - /// if is null. - public ECDsaCng(CngKey key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - - if (!IsEccAlgorithmGroup(key.AlgorithmGroup)) - throw new ArgumentException(SR.Cryptography_ArgECDsaRequiresECDsaKey, nameof(key)); - - Key = CngAlgorithmCore.Duplicate(key); - } - - protected override void Dispose(bool disposing) - { - _core.Dispose(); - } - - private void ThrowIfDisposed() - { - _core.ThrowIfDisposed(); - } - - private void DisposeKey() - { - _core.DisposeKey(); - } - - private static bool IsEccAlgorithmGroup(CngAlgorithmGroup? algorithmGroup) - { - // Sometimes, when reading from certificates, ECDSA keys get identified as ECDH. - // Windows allows the ECDH keys to perform both key exchange (ECDH) and signing (ECDSA), - // so either value is acceptable for the ECDSA wrapper object. - // - // It is worth noting, however, that ECDSA-identified keys cannot be used for key exchange (ECDH) in CNG. - return algorithmGroup == CngAlgorithmGroup.ECDsa || algorithmGroup == CngAlgorithmGroup.ECDiffieHellman; - } - - internal string? GetCurveName(out string? oidValue) - { - return Key.GetCurveName(out oidValue); - } - - private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters) - { - Key = ECCng.ImportFullKeyBlob(ecfullKeyBlob, includePrivateParameters); - } - - private void ImportKeyBlob(byte[] ecfullKeyBlob, string curveName, bool includePrivateParameters) - { - Key = ECCng.ImportKeyBlob(ecfullKeyBlob, curveName, includePrivateParameters); - } - - private byte[] ExportKeyBlob(bool includePrivateParameters) - { - return ECCng.ExportKeyBlob(Key, includePrivateParameters); - } - - private byte[] ExportFullKeyBlob(bool includePrivateParameters) - { - return ECCng.ExportFullKeyBlob(Key, includePrivateParameters); - } - - private void AcceptImport(CngPkcs8.Pkcs8Response response) - { - Key = response.Key; - } - - public override bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritten) - { - return Key.TryExportKeyBlob( - Interop.NCrypt.NCRYPT_PKCS8_PRIVATE_KEY_BLOB, - destination, - out bytesWritten); - } - - private byte[] ExportEncryptedPkcs8(ReadOnlySpan pkcs8Password, int kdfCount) - { - return Key.ExportPkcs8KeyBlob(pkcs8Password, kdfCount); - } - - private bool TryExportEncryptedPkcs8( - ReadOnlySpan pkcs8Password, - int kdfCount, - Span destination, - out int bytesWritten) - { - return Key.TryExportPkcs8KeyBlob( - pkcs8Password, - kdfCount, - destination, - out bytesWritten); - } - - public void FromXmlString(string xml, ECKeyXmlFormat format) - => throw new PlatformNotSupportedException(); - - public byte[] SignData(byte[] data) - => SignData(data, new HashAlgorithmName(HashAlgorithm.Algorithm)); - - public byte[] SignData(byte[] data, int offset, int count) => - SignData(data, offset, count, new HashAlgorithmName(HashAlgorithm.Algorithm)); - - public byte[] SignData(Stream data) - => SignData(data, new HashAlgorithmName(HashAlgorithm.Algorithm)); - - public string ToXmlString(ECKeyXmlFormat format) - => throw new PlatformNotSupportedException(); - - public bool VerifyData(byte[] data, byte[] signature) - => VerifyData(data, signature, new HashAlgorithmName(HashAlgorithm.Algorithm)); - - public bool VerifyData(byte[] data, int offset, int count, byte[] signature) - => VerifyData(data, offset, count, signature, new HashAlgorithmName(HashAlgorithm.Algorithm)); - - public bool VerifyData(Stream data, byte[] signature) - => VerifyData(data, signature, new HashAlgorithmName(HashAlgorithm.Algorithm)); - } -} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/RSACng.cs b/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/RSACng.cs deleted file mode 100644 index 8910ab5453dc11..00000000000000 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/RSACng.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Internal.Cryptography; - -namespace System.Security.Cryptography -{ - public sealed partial class RSACng : RSA - { - private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(RSACng)); - - /// - /// Creates a new RSACng object that will use the specified key. The key's - /// must be Rsa. This constructor - /// creates a copy of the key. Hence, the caller can safely dispose of the - /// passed in key and continue using the RSACng object. - /// - /// Key to use for RSA operations - /// if is not an RSA key - /// if is null. - public RSACng(CngKey key) - { - if (key == null) - throw new ArgumentNullException(nameof(key)); - - if (key.AlgorithmGroup != CngAlgorithmGroup.Rsa) - throw new ArgumentException(SR.Cryptography_ArgRSARequiresRSAKey, nameof(key)); - - Key = CngAlgorithmCore.Duplicate(key); - } - - protected override void Dispose(bool disposing) - { - _core.Dispose(); - } - - private void ThrowIfDisposed() - { - _core.ThrowIfDisposed(); - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.Forwards.cs b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.Forwards.cs new file mode 100644 index 00000000000000..b79fa6a3d2e104 --- /dev/null +++ b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.Forwards.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +#pragma warning disable SYSLIB0021 +#pragma warning disable SYSLIB0023 + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.AesCryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CspKeyContainerInfo))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CspParameters))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.CspProviderFlags))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DESCryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DSACryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ICspAsymmetricAlgorithm))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.KeyNumber))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.MD5CryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.PasswordDeriveBytes))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RC2CryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RNGCryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSACryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA1CryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA256CryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA384CryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SHA512CryptoServiceProvider))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.TripleDESCryptoServiceProvider))] diff --git a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs deleted file mode 100644 index c266badaac767a..00000000000000 --- a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.cs +++ /dev/null @@ -1,306 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// ------------------------------------------------------------------------------ -// Changes to this file must follow the https://aka.ms/api-review process. -// ------------------------------------------------------------------------------ - -namespace System.Security.Cryptography -{ - [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class AesCryptoServiceProvider : System.Security.Cryptography.Aes - { - public AesCryptoServiceProvider() { } - public override int BlockSize { get { throw null; } set { } } - public override int FeedbackSize { get { throw null; } set { } } - public override byte[] IV { get { throw null; } set { } } - public override byte[] Key { get { throw null; } set { } } - public override int KeySize { get { throw null; } set { } } - public override System.Security.Cryptography.KeySizes[] LegalBlockSizes { get { throw null; } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - public override System.Security.Cryptography.CipherMode Mode { get { throw null; } set { } } - public override System.Security.Cryptography.PaddingMode Padding { get { throw null; } set { } } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - protected override void Dispose(bool disposing) { } - public override void GenerateIV() { } - public override void GenerateKey() { } - } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public sealed partial class CspKeyContainerInfo - { - public CspKeyContainerInfo(System.Security.Cryptography.CspParameters parameters) { } - public bool Accessible { get { throw null; } } - public bool Exportable { get { throw null; } } - public bool HardwareDevice { get { throw null; } } - public string? KeyContainerName { get { throw null; } } - public System.Security.Cryptography.KeyNumber KeyNumber { get { throw null; } } - public bool MachineKeyStore { get { throw null; } } - public bool Protected { get { throw null; } } - public string? ProviderName { get { throw null; } } - public int ProviderType { get { throw null; } } - public bool RandomlyGenerated { get { throw null; } } - public bool Removable { get { throw null; } } - public string UniqueKeyContainerName { get { throw null; } } - } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public sealed partial class CspParameters - { - public string? KeyContainerName; - public int KeyNumber; - public string? ProviderName; - public int ProviderType; - public CspParameters() { } - public CspParameters(int dwTypeIn) { } - public CspParameters(int dwTypeIn, string? strProviderNameIn) { } - public CspParameters(int dwTypeIn, string? strProviderNameIn, string? strContainerNameIn) { } - public System.Security.Cryptography.CspProviderFlags Flags { get { throw null; } set { } } - [System.CLSCompliantAttribute(false)] - public System.Security.SecureString? KeyPassword { get { throw null; } set { } } - public System.IntPtr ParentWindowHandle { get { throw null; } set { } } - } - [System.FlagsAttribute] - public enum CspProviderFlags - { - NoFlags = 0, - UseMachineKeyStore = 1, - UseDefaultKeyContainer = 2, - UseNonExportableKey = 4, - UseExistingKey = 8, - UseArchivableKey = 16, - UseUserProtectedKey = 32, - NoPrompt = 64, - CreateEphemeralKey = 128, - } - [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class DESCryptoServiceProvider : System.Security.Cryptography.DES - { - public DESCryptoServiceProvider() { } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - public override void GenerateIV() { } - public override void GenerateKey() { } - } - public sealed partial class DSACryptoServiceProvider : System.Security.Cryptography.DSA, System.Security.Cryptography.ICspAsymmetricAlgorithm - { - public DSACryptoServiceProvider() { } - public DSACryptoServiceProvider(int dwKeySize) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public DSACryptoServiceProvider(int dwKeySize, System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public DSACryptoServiceProvider(System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get { throw null; } } - public override string? KeyExchangeAlgorithm { get { throw null; } } - public override int KeySize { get { throw null; } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - public bool PersistKeyInCsp { get { throw null; } set { } } - public bool PublicOnly { get { throw null; } } - public override string SignatureAlgorithm { get { throw null; } } - public static bool UseMachineKeyStore { get { throw null; } set { } } - public override byte[] CreateSignature(byte[] rgbHash) { throw null; } - protected override void Dispose(bool disposing) { } - public byte[] ExportCspBlob(bool includePrivateParameters) { throw null; } - public override System.Security.Cryptography.DSAParameters ExportParameters(bool includePrivateParameters) { throw null; } - protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public void ImportCspBlob(byte[] keyBlob) { } - public override void ImportParameters(System.Security.Cryptography.DSAParameters parameters) { } - public byte[] SignData(byte[] buffer) { throw null; } - public byte[] SignData(byte[] buffer, int offset, int count) { throw null; } - public byte[] SignData(System.IO.Stream inputStream) { throw null; } - public byte[] SignHash(byte[] rgbHash, string? str) { throw null; } - public bool VerifyData(byte[] rgbData, byte[] rgbSignature) { throw null; } - public bool VerifyHash(byte[] rgbHash, string? str, byte[] rgbSignature) { throw null; } - public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) { throw null; } - } - public partial interface ICspAsymmetricAlgorithm - { - System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get; } - byte[] ExportCspBlob(bool includePrivateParameters); - void ImportCspBlob(byte[] rawData); - } - public enum KeyNumber - { - Exchange = 1, - Signature = 2, - } - [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class MD5CryptoServiceProvider : System.Security.Cryptography.MD5 - { - public MD5CryptoServiceProvider() { } - protected override void Dispose(bool disposing) { } - protected override void HashCore(byte[] array, int ibStart, int cbSize) { } - protected override void HashCore(System.ReadOnlySpan source) { } - protected override byte[] HashFinal() { throw null; } - public override void Initialize() { } - protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } - } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public partial class PasswordDeriveBytes : System.Security.Cryptography.DeriveBytes - { - public PasswordDeriveBytes(byte[] password, byte[]? salt) { } - public PasswordDeriveBytes(byte[] password, byte[]? salt, System.Security.Cryptography.CspParameters? cspParams) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] - public PasswordDeriveBytes(byte[] password, byte[]? salt, string hashName, int iterations) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] - public PasswordDeriveBytes(byte[] password, byte[]? salt, string hashName, int iterations, System.Security.Cryptography.CspParameters? cspParams) { } - public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt) { } - public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt, System.Security.Cryptography.CspParameters? cspParams) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] - public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt, string strHashName, int iterations) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] - public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt, string strHashName, int iterations, System.Security.Cryptography.CspParameters? cspParams) { } - public string HashName { get { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] set { } } - public int IterationCount { get { throw null; } set { } } - public byte[]? Salt { get { throw null; } set { } } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public byte[] CryptDeriveKey(string? algname, string? alghashname, int keySize, byte[] rgbIV) { throw null; } - protected override void Dispose(bool disposing) { } - [System.ObsoleteAttribute("Rfc2898DeriveBytes replaces PasswordDeriveBytes for deriving key material from a password and is preferred in new applications.")] - public override byte[] GetBytes(int cb) { throw null; } - public override void Reset() { } - } - [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class RC2CryptoServiceProvider : System.Security.Cryptography.RC2 - { - public RC2CryptoServiceProvider() { } - public override int EffectiveKeySize { get { throw null; } set { } } - public bool UseSalt { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - public override void GenerateIV() { } - public override void GenerateKey() { } - } - [System.ObsoleteAttribute("RNGCryptoServiceProvider is obsolete. To generate a random number, use one of the RandomNumberGenerator static methods instead.", DiagnosticId = "SYSLIB0023", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class RNGCryptoServiceProvider : System.Security.Cryptography.RandomNumberGenerator - { - public RNGCryptoServiceProvider() { } - public RNGCryptoServiceProvider(byte[] rgb) { } - public RNGCryptoServiceProvider(System.Security.Cryptography.CspParameters? cspParams) { } - public RNGCryptoServiceProvider(string str) { } - protected override void Dispose(bool disposing) { } - public override void GetBytes(byte[] data) { } - public override void GetBytes(byte[] data, int offset, int count) { } - public override void GetBytes(System.Span data) { } - public override void GetNonZeroBytes(byte[] data) { } - public override void GetNonZeroBytes(System.Span data) { } - } - public sealed partial class RSACryptoServiceProvider : System.Security.Cryptography.RSA, System.Security.Cryptography.ICspAsymmetricAlgorithm - { - public RSACryptoServiceProvider() { } - public RSACryptoServiceProvider(int dwKeySize) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public RSACryptoServiceProvider(int dwKeySize, System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public RSACryptoServiceProvider(System.Security.Cryptography.CspParameters? parameters) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get { throw null; } } - public override string? KeyExchangeAlgorithm { get { throw null; } } - public override int KeySize { get { throw null; } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - public bool PersistKeyInCsp { get { throw null; } set { } } - public bool PublicOnly { get { throw null; } } - public override string SignatureAlgorithm { get { throw null; } } - public static bool UseMachineKeyStore { get { throw null; } set { } } - public byte[] Decrypt(byte[] rgb, bool fOAEP) { throw null; } - public override byte[] Decrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } - public override byte[] DecryptValue(byte[] rgb) { throw null; } - protected override void Dispose(bool disposing) { } - public byte[] Encrypt(byte[] rgb, bool fOAEP) { throw null; } - public override byte[] Encrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } - public override byte[] EncryptValue(byte[] rgb) { throw null; } - public byte[] ExportCspBlob(bool includePrivateParameters) { throw null; } - public override System.Security.Cryptography.RSAParameters ExportParameters(bool includePrivateParameters) { throw null; } - protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public void ImportCspBlob(byte[] keyBlob) { } - public override void ImportParameters(System.Security.Cryptography.RSAParameters parameters) { } - public byte[] SignData(byte[] buffer, int offset, int count, object halg) { throw null; } - public byte[] SignData(byte[] buffer, object halg) { throw null; } - public byte[] SignData(System.IO.Stream inputStream, object halg) { throw null; } - public override byte[] SignHash(byte[] hash, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } - public byte[] SignHash(byte[] rgbHash, string? str) { throw null; } - public bool VerifyData(byte[] buffer, object halg, byte[] signature) { throw null; } - public override bool VerifyHash(byte[] hash, byte[] signature, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } - public bool VerifyHash(byte[] rgbHash, string str, byte[] rgbSignature) { throw null; } - } - [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class SHA1CryptoServiceProvider : System.Security.Cryptography.SHA1 - { - public SHA1CryptoServiceProvider() { } - protected override void Dispose(bool disposing) { } - protected override void HashCore(byte[] array, int ibStart, int cbSize) { } - protected override void HashCore(System.ReadOnlySpan source) { } - protected override byte[] HashFinal() { throw null; } - public override void Initialize() { } - protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } - } - [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class SHA256CryptoServiceProvider : System.Security.Cryptography.SHA256 - { - public SHA256CryptoServiceProvider() { } - protected override void Dispose(bool disposing) { } - protected override void HashCore(byte[] array, int ibStart, int cbSize) { } - protected override void HashCore(System.ReadOnlySpan source) { } - protected override byte[] HashFinal() { throw null; } - public override void Initialize() { } - protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } - } - [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class SHA384CryptoServiceProvider : System.Security.Cryptography.SHA384 - { - public SHA384CryptoServiceProvider() { } - protected override void Dispose(bool disposing) { } - protected override void HashCore(byte[] array, int ibStart, int cbSize) { } - protected override void HashCore(System.ReadOnlySpan source) { } - protected override byte[] HashFinal() { throw null; } - public override void Initialize() { } - protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } - } - [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class SHA512CryptoServiceProvider : System.Security.Cryptography.SHA512 - { - public SHA512CryptoServiceProvider() { } - protected override void Dispose(bool disposing) { } - protected override void HashCore(byte[] array, int ibStart, int cbSize) { } - protected override void HashCore(System.ReadOnlySpan source) { } - protected override byte[] HashFinal() { throw null; } - public override void Initialize() { } - protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } - } - [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public sealed partial class TripleDESCryptoServiceProvider : System.Security.Cryptography.TripleDES - { - public TripleDESCryptoServiceProvider() { } - public override int BlockSize { get { throw null; } set { } } - public override int FeedbackSize { get { throw null; } set { } } - public override byte[] IV { get { throw null; } set { } } - public override byte[] Key { get { throw null; } set { } } - public override int KeySize { get { throw null; } set { } } - public override System.Security.Cryptography.KeySizes[] LegalBlockSizes { get { throw null; } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - public override System.Security.Cryptography.CipherMode Mode { get { throw null; } set { } } - public override System.Security.Cryptography.PaddingMode Padding { get { throw null; } set { } } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } - public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } - protected override void Dispose(bool disposing) { } - public override void GenerateIV() { } - public override void GenerateKey() { } - } -} diff --git a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.csproj b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.csproj index 91c4d14e1db97c..19181bd717eef8 100644 --- a/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.csproj +++ b/src/libraries/System.Security.Cryptography.Csp/ref/System.Security.Cryptography.Csp.csproj @@ -5,7 +5,7 @@ enable - + diff --git a/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/Helpers.cs b/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/Helpers.cs deleted file mode 100644 index 9b70db3eff4195..00000000000000 --- a/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/Helpers.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Security.Cryptography; - -namespace Internal.Cryptography -{ - internal static partial class Helpers - { - public static bool UsesIv(this CipherMode cipherMode) - { - return cipherMode != CipherMode.ECB; - } - - public static byte[]? GetCipherIv(this CipherMode cipherMode, byte[]? iv) - { - if (cipherMode.UsesIv()) - { - if (iv == null) - { - throw new CryptographicException(SR.Cryptography_MissingIV); - } - - return iv; - } - - return null; - } - - public static byte[]? TrimLargeIV(byte[]? currentIV, int blockSizeInBits) - { - int blockSizeBytes = checked((blockSizeInBits + 7) / 8); - - if (currentIV?.Length > blockSizeBytes) - { - byte[] tmp = new byte[blockSizeBytes]; - Buffer.BlockCopy(currentIV, 0, tmp, 0, tmp.Length); - return tmp; - } - - return currentIV; - } - } -} diff --git a/src/libraries/System.Security.Cryptography.Csp/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography.Csp/src/Resources/Strings.resx deleted file mode 100644 index 16480c8488ab7a..00000000000000 --- a/src/libraries/System.Security.Cryptography.Csp/src/Resources/Strings.resx +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Illegal enum value: {0}. - - - Value was invalid. - - - Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. - - - Non-negative number required. - - - Positive number required. - - - '{0}' requires Windows Cryptographic API (CAPI), which is not available on this platform. - - - Object contains only the public half of a key pair. A private key must also be provided. - - - The requested key container was not found. - - - The specified cryptographic service provider (CSP) does not support this key algorithm: {0}. - - - Length of the DSA signature was not 40 bytes. - - - {0} algorithm hash size is {1} bytes. - - - Specified initialization vector (IV) does not match the block size for this algorithm. - - - Specified key is a known weak key for '{0}' and cannot be used. - - - Specified key is a known semi-weak key for '{0}' and cannot be used. - - - Specified key is not a valid size for this algorithm. - - - Object identifier (OID) is unknown. - - - Padding is invalid and cannot be removed. - - - Specified padding mode is not valid for this algorithm. - - - The cipher mode specified requires that an initialization vector (IV) be used. - - - TransformBlock may only process bytes in block sized increments. - - - Cannot open an invalid handle. - - - The input data is not a complete block. - - - Algorithm is unavailable or is not supported for this operation. - - - The Initialization vector should have the same length as the algorithm block size in bytes. - - - Requested number of bytes exceeds the maximum. - - - Value of '{0}' cannot be changed after the bytes have been retrieved. - - - EffectiveKeySize must be the same as KeySize in this implementation. - - - The length of the data to decrypt is not valid for the size of this key. - - - '{0}' is not a known hash algorithm. - - - Unknown padding mode used. - - - CryptSetKeyParam failed with error code {0}. - - - CSPParameters cannot be null - - - System.Security.Cryptography.Csp is not supported on this platform. - - - Destination is too short. - - diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System.Security.Cryptography.Csp.csproj b/src/libraries/System.Security.Cryptography.Csp/src/System.Security.Cryptography.Csp.csproj index 92886ecfd15fe1..722700b99b1517 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System.Security.Cryptography.Csp.csproj +++ b/src/libraries/System.Security.Cryptography.Csp/src/System.Security.Cryptography.Csp.csproj @@ -1,139 +1,12 @@ - true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent) - enable + true + $(NetCoreAppCurrent) - - $(NoWarn);CS0809 - SR.SystemSecurityCryptographyCsp_PlatformNotSupported - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Unix.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Unix.cs deleted file mode 100644 index 960e89383a88a9..00000000000000 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Unix.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Security.Cryptography; - -namespace Internal.NativeCrypto -{ - internal static partial class CapiHelper - { - public static CryptographicException GetBadDataException() - { - const int NTE_BAD_DATA = unchecked((int)CryptKeyError.NTE_BAD_DATA); - return new CryptographicException(NTE_BAD_DATA); - } - - public static CryptographicException GetEFailException() - { - return new CryptographicException(E_FAIL); - } - } -} diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.Forwards.cs b/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.Forwards.cs new file mode 100644 index 00000000000000..436f6161c56386 --- /dev/null +++ b/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.Forwards.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.DSAOpenSsl))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECDiffieHellmanOpenSsl))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.ECDsaOpenSsl))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.RSAOpenSsl))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.SafeEvpPKeyHandle))] diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.cs b/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.cs deleted file mode 100644 index 49a2aa2e1bbf20..00000000000000 --- a/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// ------------------------------------------------------------------------------ -// Changes to this file must follow the https://aka.ms/api-review process. -// ------------------------------------------------------------------------------ - -namespace System.Security.Cryptography -{ - public sealed class DSAOpenSsl : System.Security.Cryptography.DSA - { - public DSAOpenSsl() { } - public DSAOpenSsl(int keySize) { } - public DSAOpenSsl(System.IntPtr handle) { } - public DSAOpenSsl(System.Security.Cryptography.DSAParameters parameters) { } - public DSAOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) { } - public override int KeySize { set { } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - public override byte[] CreateSignature(byte[] rgbHash) { throw null; } - protected override void Dispose(bool disposing) { } - public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } - public override System.Security.Cryptography.DSAParameters ExportParameters(bool includePrivateParameters) { throw null; } - protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public override void ImportParameters(System.Security.Cryptography.DSAParameters parameters) { } - public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) { throw null; } - } - public sealed class ECDiffieHellmanOpenSsl : System.Security.Cryptography.ECDiffieHellman - { - public ECDiffieHellmanOpenSsl() { } - public ECDiffieHellmanOpenSsl(int keySize) { } - public ECDiffieHellmanOpenSsl(System.IntPtr handle) { } - public ECDiffieHellmanOpenSsl(System.Security.Cryptography.ECCurve curve) { } - public ECDiffieHellmanOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) { } - public override System.Security.Cryptography.ECDiffieHellmanPublicKey PublicKey { get { throw null; } } - public override byte[] DeriveKeyFromHash(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[]? secretPrepend, byte[]? secretAppend) { throw null; } - public override byte[] DeriveKeyFromHmac(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[]? hmacKey, byte[]? secretPrepend, byte[]? secretAppend) { throw null; } - public override byte[] DeriveKeyMaterial(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey) { throw null; } - public override byte[] DeriveKeyTls(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed) { throw null; } - public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } - public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters) { throw null; } - public override System.Security.Cryptography.ECParameters ExportParameters(bool includePrivateParameters) { throw null; } - public override void GenerateKey(System.Security.Cryptography.ECCurve curve) { } - public override void ImportParameters(System.Security.Cryptography.ECParameters parameters) { } - } - public sealed class ECDsaOpenSsl : System.Security.Cryptography.ECDsa - { - public ECDsaOpenSsl() { } - public ECDsaOpenSsl(int keySize) { } - public ECDsaOpenSsl(System.IntPtr handle) { } - public ECDsaOpenSsl(System.Security.Cryptography.ECCurve curve) { } - public ECDsaOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) { } - public override int KeySize { get { throw null; } set { } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - protected override void Dispose(bool disposing) { } - public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } - public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters) { throw null; } - public override System.Security.Cryptography.ECParameters ExportParameters(bool includePrivateParameters) { throw null; } - public override void GenerateKey(System.Security.Cryptography.ECCurve curve) { } - protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public override void ImportParameters(System.Security.Cryptography.ECParameters parameters) { } - public override byte[] SignHash(byte[] hash) { throw null; } - public override bool VerifyHash(byte[] hash, byte[] signature) { throw null; } - } - public sealed class RSAOpenSsl : System.Security.Cryptography.RSA - { - public RSAOpenSsl() { } - public RSAOpenSsl(int keySize) { } - public RSAOpenSsl(System.IntPtr handle) { } - public RSAOpenSsl(System.Security.Cryptography.RSAParameters parameters) { } - public RSAOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) { } - public override int KeySize { set { } } - public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } - public override byte[] Decrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } - protected override void Dispose(bool disposing) { } - public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } - public override byte[] Encrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } - public override System.Security.Cryptography.RSAParameters ExportParameters(bool includePrivateParameters) { throw null; } - protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public override void ImportParameters(System.Security.Cryptography.RSAParameters parameters) { } - public override byte[] SignHash(byte[] hash, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } - public override bool VerifyHash(byte[] hash, byte[] signature, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } - } - public sealed class SafeEvpPKeyHandle : System.Runtime.InteropServices.SafeHandle - { - public SafeEvpPKeyHandle() : base (default(System.IntPtr), default(bool)) { } - public SafeEvpPKeyHandle(System.IntPtr handle, bool ownsHandle) : base (default(System.IntPtr), default(bool)) { } - public static long OpenSslVersion { get { throw null; } } - public override bool IsInvalid { get { throw null; } } - public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateHandle() { throw null; } - protected override bool ReleaseHandle() { throw null; } - } -} diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj b/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj index 2dd57d852f4c95..225e8cf6880823 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj +++ b/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj @@ -4,11 +4,10 @@ enable - + - diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography.OpenSsl/src/Resources/Strings.resx deleted file mode 100644 index f44ab3d72e541c..00000000000000 --- a/src/libraries/System.Security.Cryptography.OpenSsl/src/Resources/Strings.resx +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Error occurred during a cryptographic operation. - - - The destination is too small to hold the encoded value. - - - The OID value was invalid. - - - Value was invalid. - - - The keys from both parties must be the same size to generate a secret agreement. - - - Object contains only the public half of a key pair. A private key must also be provided. - - - The message exceeds the maximum allowable length for the chosen options ({0}). - - - The specified curve '{0}' or its parameters are not valid for this platform. - - - ASN1 corrupted data. - - - The specified DSA parameters are not valid; P, Q, G and Y are all required. - - - The specified DSA parameters are not valid; P, G and Y must be the same length (the key size). - - - The specified DSA parameters are not valid; Q and X (if present) must be the same length. - - - The specified DSA parameters are not valid; J (if present) must be shorter than P. - - - The specified DSA parameters are not valid; Seed, if present, must be 20 bytes long for keys shorter than 1024 bits. - - - The specified DSA parameters are not valid; Q must be 20 bytes long for keys shorter than 1024 bits. - - - The specified DSA parameters are not valid; Q's length must be one of 20, 32 or 64 bytes. - - - Specified key is not a valid size for this algorithm. - - - Specified padding mode is not valid for this algorithm. - - - The specified RSA parameters are not valid. Exponent and Modulus are required. If D is present, it must have the same length as Modulus. If D is present, P, Q, DP, DQ, and InverseQ are required and must have half the length of Modulus, rounded up, otherwise they must be omitted. - - - Key is not a valid private key. - - - Cannot open an invalid handle. - - - The provided RSAPrivateKey value has version '{0}', but version '{1}' is the maximum supported. - - - The TLS key derivation function requires a seed value of exactly 64 bytes. - - - '{0}' is not a known hash algorithm. - - - The string contains a character not in the 7 bit ASCII character set. - - - The key is too small for the requested operation. - - - Error occurred while decoding OAEP padding. - - - The length of the data to decrypt is not valid for the size of this key. - - - The provided hash value is not the expected size for the specified hash algorithm. - - - Key is not a valid public or private key. - - - Algorithm '{0}' is not supported on this platform. - - - OpenSSL is not supported on this platform. - - diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj b/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj index 2f01f9432c0d1c..1fe031a388f591 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj +++ b/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj @@ -1,173 +1,10 @@ - $(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent) - true - enable + $(NetCoreAppCurrent) + true - - SR.PlatformNotSupported_CryptographyOpenSSL - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml - - - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml.cs - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml - - - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.manual.cs - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml - - - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml - - - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml.cs - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml - - - Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\RSAPrivateKeyAsn.xml - - - Common\System\Security\Cryptography\Asn1\RSAPrivateKeyAsn.xml.cs - Common\System\Security\Cryptography\Asn1\RSAPrivateKeyAsn.xml - - - Common\System\Security\Cryptography\Asn1\RSAPublicKeyAsn.xml - - - Common\System\Security\Cryptography\Asn1\RSAPublicKeyAsn.xml.cs - Common\System\Security\Cryptography\Asn1\RSAPublicKeyAsn.xml - - - Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml - - - - - - - - - - - - - - - - - - diff --git a/src/libraries/System.Security.Cryptography.Pkcs/NuGet.config b/src/libraries/System.Security.Cryptography.Pkcs/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Security.Cryptography.Pkcs/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj b/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj index c0c2da22f98513..4b46896972cdb5 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj @@ -4,7 +4,7 @@ true $(NoWarn);CA5384 enable - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.1-windows;netstandard2.1;netstandard2.0-windows;netstandard2.0;$(NetFrameworkMinimum) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum) true Provides support for PKCS and CMS algorithms. diff --git a/src/libraries/System.Security.Cryptography.ProtectedData/NuGet.config b/src/libraries/System.Security.Cryptography.ProtectedData/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Security.Cryptography.ProtectedData/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.ProtectedData/src/System.Security.Cryptography.ProtectedData.csproj b/src/libraries/System.Security.Cryptography.ProtectedData/src/System.Security.Cryptography.ProtectedData.csproj index 2ed84aad3ce8ea..7307e2d836b798 100644 --- a/src/libraries/System.Security.Cryptography.ProtectedData/src/System.Security.Cryptography.ProtectedData.csproj +++ b/src/libraries/System.Security.Cryptography.ProtectedData/src/System.Security.Cryptography.ProtectedData.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0-windows;netstandard2.0;$(NetFrameworkMinimum) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) enable true true diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/NuGet.config b/src/libraries/System.Security.Cryptography.X509Certificates/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Security.Cryptography.X509Certificates/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.Forwards.cs b/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.Forwards.cs new file mode 100644 index 00000000000000..6827f78966d522 --- /dev/null +++ b/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.Forwards.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Win32.SafeHandles.SafeX509ChainHandle))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.CertificateRequest))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.DSACertificateExtensions))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.ECDsaCertificateExtensions))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.OpenFlags))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.PublicKey))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.RSACertificateExtensions))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.StoreLocation))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.StoreName))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.SubjectAlternativeNameBuilder))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X500DistinguishedName))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509Certificate))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509Certificate2))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509Certificate2Collection))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509Certificate2Enumerator))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509CertificateCollection))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509Chain))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ChainElement))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ChainElementCollection))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ChainElementEnumerator))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ChainPolicy))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ChainStatus))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ChainStatusFlags))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ChainTrustMode))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ContentType))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509Extension))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ExtensionCollection))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509ExtensionEnumerator))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509FindType))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509IncludeOption))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509KeyStorageFlags))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509KeyUsageExtension))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509KeyUsageFlags))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509NameType))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509RevocationFlag))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509RevocationMode))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509SignatureGenerator))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509Store))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierExtension))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierHashAlgorithm))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Cryptography.X509Certificates.X509VerificationFlags))] diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs b/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs deleted file mode 100644 index ba1ff3b66349f9..00000000000000 --- a/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.cs +++ /dev/null @@ -1,684 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// ------------------------------------------------------------------------------ -// Changes to this file must follow the https://aka.ms/api-review process. -// ------------------------------------------------------------------------------ - -namespace Microsoft.Win32.SafeHandles -{ - public sealed partial class SafeX509ChainHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid - { - public SafeX509ChainHandle() : base (default(bool)) { } - protected override void Dispose(bool disposing) { } - protected override bool ReleaseHandle() { throw null; } - } -} -namespace System.Security.Cryptography.X509Certificates -{ - public sealed partial class CertificateRequest - { - public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.ECDsa key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { } - public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.RSA key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { } - public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.X509Certificates.PublicKey publicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { } - public CertificateRequest(string subjectName, System.Security.Cryptography.ECDsa key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { } - public CertificateRequest(string subjectName, System.Security.Cryptography.RSA key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { } - public System.Collections.ObjectModel.Collection CertificateExtensions { get { throw null; } } - public System.Security.Cryptography.HashAlgorithmName HashAlgorithm { get { throw null; } } - public System.Security.Cryptography.X509Certificates.PublicKey PublicKey { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X500DistinguishedName SubjectName { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509Certificate2 Create(System.Security.Cryptography.X509Certificates.X500DistinguishedName issuerName, System.Security.Cryptography.X509Certificates.X509SignatureGenerator generator, System.DateTimeOffset notBefore, System.DateTimeOffset notAfter, byte[] serialNumber) { throw null; } - public System.Security.Cryptography.X509Certificates.X509Certificate2 Create(System.Security.Cryptography.X509Certificates.X500DistinguishedName issuerName, System.Security.Cryptography.X509Certificates.X509SignatureGenerator generator, System.DateTimeOffset notBefore, System.DateTimeOffset notAfter, System.ReadOnlySpan serialNumber) { throw null; } - public System.Security.Cryptography.X509Certificates.X509Certificate2 Create(System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCertificate, System.DateTimeOffset notBefore, System.DateTimeOffset notAfter, byte[] serialNumber) { throw null; } - public System.Security.Cryptography.X509Certificates.X509Certificate2 Create(System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCertificate, System.DateTimeOffset notBefore, System.DateTimeOffset notAfter, System.ReadOnlySpan serialNumber) { throw null; } - public System.Security.Cryptography.X509Certificates.X509Certificate2 CreateSelfSigned(System.DateTimeOffset notBefore, System.DateTimeOffset notAfter) { throw null; } - public byte[] CreateSigningRequest() { throw null; } - public byte[] CreateSigningRequest(System.Security.Cryptography.X509Certificates.X509SignatureGenerator signatureGenerator) { throw null; } - } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] - public static partial class DSACertificateExtensions - { - public static System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate, System.Security.Cryptography.DSA privateKey) { throw null; } - public static System.Security.Cryptography.DSA? GetDSAPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } - public static System.Security.Cryptography.DSA? GetDSAPublicKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } - } - public static partial class ECDsaCertificateExtensions - { - public static System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate, System.Security.Cryptography.ECDsa privateKey) { throw null; } - public static System.Security.Cryptography.ECDsa? GetECDsaPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } - public static System.Security.Cryptography.ECDsa? GetECDsaPublicKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } - } - [System.FlagsAttribute] - public enum OpenFlags - { - ReadOnly = 0, - ReadWrite = 1, - MaxAllowed = 2, - OpenExistingOnly = 4, - IncludeArchived = 8, - } - public sealed partial class PublicKey - { - public PublicKey(System.Security.Cryptography.AsymmetricAlgorithm key) { } - public PublicKey(System.Security.Cryptography.Oid oid, System.Security.Cryptography.AsnEncodedData parameters, System.Security.Cryptography.AsnEncodedData keyValue) { } - public System.Security.Cryptography.AsnEncodedData EncodedKeyValue { get { throw null; } } - public System.Security.Cryptography.AsnEncodedData EncodedParameters { get { throw null; } } - [System.ObsoleteAttribute("PublicKey.Key is obsolete. Use the appropriate method to get the public key, such as GetRSAPublicKey.", DiagnosticId = "SYSLIB0027", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public System.Security.Cryptography.AsymmetricAlgorithm Key { get { throw null; } } - public System.Security.Cryptography.Oid Oid { get { throw null; } } - public static System.Security.Cryptography.X509Certificates.PublicKey CreateFromSubjectPublicKeyInfo(System.ReadOnlySpan source, out int bytesRead) { throw null; } - public byte[] ExportSubjectPublicKeyInfo() { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] - public System.Security.Cryptography.DSA? GetDSAPublicKey() { throw null; } - public System.Security.Cryptography.ECDiffieHellman? GetECDiffieHellmanPublicKey() { throw null; } - public System.Security.Cryptography.ECDsa? GetECDsaPublicKey() { throw null; } - public System.Security.Cryptography.RSA? GetRSAPublicKey() { throw null; } - public bool TryExportSubjectPublicKeyInfo(System.Span destination, out int bytesWritten) { throw null; } - } - public static partial class RSACertificateExtensions - { - public static System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate, System.Security.Cryptography.RSA privateKey) { throw null; } - public static System.Security.Cryptography.RSA? GetRSAPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } - public static System.Security.Cryptography.RSA? GetRSAPublicKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } - } - public enum StoreLocation - { - CurrentUser = 1, - LocalMachine = 2, - } - public enum StoreName - { - AddressBook = 1, - AuthRoot = 2, - CertificateAuthority = 3, - Disallowed = 4, - My = 5, - Root = 6, - TrustedPeople = 7, - TrustedPublisher = 8, - } - public sealed partial class SubjectAlternativeNameBuilder - { - public SubjectAlternativeNameBuilder() { } - public void AddDnsName(string dnsName) { } - public void AddEmailAddress(string emailAddress) { } - public void AddIpAddress(System.Net.IPAddress ipAddress) { } - public void AddUri(System.Uri uri) { } - public void AddUserPrincipalName(string upn) { } - public System.Security.Cryptography.X509Certificates.X509Extension Build(bool critical = false) { throw null; } - } - public sealed partial class X500DistinguishedName : System.Security.Cryptography.AsnEncodedData - { - public X500DistinguishedName(byte[] encodedDistinguishedName) { } - public X500DistinguishedName(System.ReadOnlySpan encodedDistinguishedName) { } - public X500DistinguishedName(System.Security.Cryptography.AsnEncodedData encodedDistinguishedName) { } - public X500DistinguishedName(System.Security.Cryptography.X509Certificates.X500DistinguishedName distinguishedName) { } - public X500DistinguishedName(string distinguishedName) { } - public X500DistinguishedName(string distinguishedName, System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags flag) { } - public string Name { get { throw null; } } - public string Decode(System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags flag) { throw null; } - public override string Format(bool multiLine) { throw null; } - } - [System.FlagsAttribute] - public enum X500DistinguishedNameFlags - { - None = 0, - Reversed = 1, - UseSemicolons = 16, - DoNotUsePlusSign = 32, - DoNotUseQuotes = 64, - UseCommas = 128, - UseNewLines = 256, - UseUTF8Encoding = 4096, - UseT61Encoding = 8192, - ForceUTF8Encoding = 16384, - } - public sealed partial class X509BasicConstraintsExtension : System.Security.Cryptography.X509Certificates.X509Extension - { - public X509BasicConstraintsExtension() { } - public X509BasicConstraintsExtension(bool certificateAuthority, bool hasPathLengthConstraint, int pathLengthConstraint, bool critical) { } - public X509BasicConstraintsExtension(System.Security.Cryptography.AsnEncodedData encodedBasicConstraints, bool critical) { } - public bool CertificateAuthority { get { throw null; } } - public bool HasPathLengthConstraint { get { throw null; } } - public int PathLengthConstraint { get { throw null; } } - public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } - } - public partial class X509Certificate : System.IDisposable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable - { - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public X509Certificate() { } - public X509Certificate(byte[] data) { } - [System.CLSCompliantAttribute(false)] - public X509Certificate(byte[] rawData, System.Security.SecureString? password) { } - [System.CLSCompliantAttribute(false)] - public X509Certificate(byte[] rawData, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public X509Certificate(byte[] rawData, string? password) { } - public X509Certificate(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public X509Certificate(System.IntPtr handle) { } - public X509Certificate(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public X509Certificate(System.Security.Cryptography.X509Certificates.X509Certificate cert) { } - public X509Certificate(string fileName) { } - [System.CLSCompliantAttribute(false)] - public X509Certificate(string fileName, System.Security.SecureString? password) { } - [System.CLSCompliantAttribute(false)] - public X509Certificate(string fileName, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public X509Certificate(string fileName, string? password) { } - public X509Certificate(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public System.IntPtr Handle { get { throw null; } } - public string Issuer { get { throw null; } } - public string Subject { get { throw null; } } - public static System.Security.Cryptography.X509Certificates.X509Certificate CreateFromCertFile(string filename) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509Certificate CreateFromSignedFile(string filename) { throw null; } - public void Dispose() { } - protected virtual void Dispose(bool disposing) { } - public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } - public virtual bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.X509Certificates.X509Certificate? other) { throw null; } - public virtual byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType) { throw null; } - [System.CLSCompliantAttribute(false)] - public virtual byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, System.Security.SecureString? password) { throw null; } - public virtual byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, string? password) { throw null; } - protected static string FormatDate(System.DateTime date) { throw null; } - public virtual byte[] GetCertHash() { throw null; } - public virtual byte[] GetCertHash(System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public virtual string GetCertHashString() { throw null; } - public virtual string GetCertHashString(System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - public virtual string GetEffectiveDateString() { throw null; } - public virtual string GetExpirationDateString() { throw null; } - public virtual string GetFormat() { throw null; } - public override int GetHashCode() { throw null; } - [System.ObsoleteAttribute("X509Certificate.GetIssuerName has been deprecated. Use the Issuer property instead.")] - public virtual string GetIssuerName() { throw null; } - public virtual string GetKeyAlgorithm() { throw null; } - public virtual byte[] GetKeyAlgorithmParameters() { throw null; } - public virtual string GetKeyAlgorithmParametersString() { throw null; } - [System.ObsoleteAttribute("X509Certificate.GetName has been deprecated. Use the Subject property instead.")] - public virtual string GetName() { throw null; } - public virtual byte[] GetPublicKey() { throw null; } - public virtual string GetPublicKeyString() { throw null; } - public virtual byte[] GetRawCertData() { throw null; } - public virtual string GetRawCertDataString() { throw null; } - public virtual byte[] GetSerialNumber() { throw null; } - public virtual string GetSerialNumberString() { throw null; } - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public virtual void Import(byte[] rawData) { } - [System.CLSCompliantAttribute(false)] - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public virtual void Import(byte[] rawData, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public virtual void Import(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public virtual void Import(string fileName) { } - [System.CLSCompliantAttribute(false)] - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public virtual void Import(string fileName, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public virtual void Import(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public virtual void Reset() { } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } - void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public override string ToString() { throw null; } - public virtual string ToString(bool fVerbose) { throw null; } - public virtual bool TryGetCertHash(System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Span destination, out int bytesWritten) { throw null; } - } - public partial class X509Certificate2 : System.Security.Cryptography.X509Certificates.X509Certificate - { - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public X509Certificate2() { } - public X509Certificate2(byte[] rawData) { } - [System.CLSCompliantAttribute(false)] - public X509Certificate2(byte[] rawData, System.Security.SecureString? password) { } - [System.CLSCompliantAttribute(false)] - public X509Certificate2(byte[] rawData, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public X509Certificate2(byte[] rawData, string? password) { } - public X509Certificate2(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public X509Certificate2(System.IntPtr handle) { } - public X509Certificate2(System.ReadOnlySpan rawData) { } - public X509Certificate2(System.ReadOnlySpan rawData, System.ReadOnlySpan password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } - protected X509Certificate2(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public X509Certificate2(System.Security.Cryptography.X509Certificates.X509Certificate certificate) { } - public X509Certificate2(string fileName) { } - public X509Certificate2(string fileName, System.ReadOnlySpan password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } - [System.CLSCompliantAttribute(false)] - public X509Certificate2(string fileName, System.Security.SecureString? password) { } - [System.CLSCompliantAttribute(false)] - public X509Certificate2(string fileName, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public X509Certificate2(string fileName, string? password) { } - public X509Certificate2(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public bool Archived { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } - public System.Security.Cryptography.X509Certificates.X509ExtensionCollection Extensions { get { throw null; } } - public string FriendlyName { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } - public bool HasPrivateKey { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X500DistinguishedName IssuerName { get { throw null; } } - public System.DateTime NotAfter { get { throw null; } } - public System.DateTime NotBefore { get { throw null; } } - [System.ObsoleteAttribute("X509Certificate2.PrivateKey is obsolete. Use the appropriate method to get the private key, such as GetRSAPrivateKey, or use the CopyWithPrivateKey method to create a new instance with a private key.", DiagnosticId = "SYSLIB0028", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public System.Security.Cryptography.AsymmetricAlgorithm? PrivateKey { get { throw null; } set { } } - public System.Security.Cryptography.X509Certificates.PublicKey PublicKey { get { throw null; } } - public byte[] RawData { get { throw null; } } - public System.ReadOnlyMemory RawDataMemory { get { throw null; } } - public string SerialNumber { get { throw null; } } - public System.Security.Cryptography.Oid SignatureAlgorithm { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X500DistinguishedName SubjectName { get { throw null; } } - public string Thumbprint { get { throw null; } } - public int Version { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(System.Security.Cryptography.ECDiffieHellman privateKey) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromEncryptedPem(System.ReadOnlySpan certPem, System.ReadOnlySpan keyPem, System.ReadOnlySpan password) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromEncryptedPemFile(string certPemFilePath, System.ReadOnlySpan password, string? keyPemFilePath = null) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromPem(System.ReadOnlySpan certPem) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromPem(System.ReadOnlySpan certPem, System.ReadOnlySpan keyPem) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromPemFile(string certPemFilePath, string? keyPemFilePath = null) { throw null; } - public string ExportCertificatePem() { throw null; } - public static System.Security.Cryptography.X509Certificates.X509ContentType GetCertContentType(byte[] rawData) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509ContentType GetCertContentType(System.ReadOnlySpan rawData) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509ContentType GetCertContentType(string fileName) { throw null; } - public System.Security.Cryptography.ECDiffieHellman? GetECDiffieHellmanPrivateKey() { throw null; } - public System.Security.Cryptography.ECDiffieHellman? GetECDiffieHellmanPublicKey() { throw null; } - public string GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType nameType, bool forIssuer) { throw null; } - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public override void Import(byte[] rawData) { } - [System.CLSCompliantAttribute(false)] - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public override void Import(byte[] rawData, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public override void Import(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public override void Import(string fileName) { } - [System.CLSCompliantAttribute(false)] - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public override void Import(string fileName, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] - public override void Import(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } - public override void Reset() { } - public override string ToString() { throw null; } - public override string ToString(bool verbose) { throw null; } - public bool TryExportCertificatePem(System.Span destination, out int charsWritten) { throw null; } - public bool Verify() { throw null; } - } - public partial class X509Certificate2Collection : System.Security.Cryptography.X509Certificates.X509CertificateCollection, System.Collections.Generic.IEnumerable, System.Collections.IEnumerable - { - public X509Certificate2Collection() { } - public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } - public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } - public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { } - public new System.Security.Cryptography.X509Certificates.X509Certificate2 this[int index] { get { throw null; } set { } } - public int Add(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } - public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } - public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { } - public bool Contains(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } - public byte[]? Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType) { throw null; } - public byte[]? Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, string? password) { throw null; } - public string ExportCertificatePems() { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] - public string ExportPkcs7Pem() { throw null; } - public System.Security.Cryptography.X509Certificates.X509Certificate2Collection Find(System.Security.Cryptography.X509Certificates.X509FindType findType, object findValue, bool validOnly) { throw null; } - public new System.Security.Cryptography.X509Certificates.X509Certificate2Enumerator GetEnumerator() { throw null; } - public void Import(byte[] rawData) { } - public void Import(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } - public void Import(System.ReadOnlySpan rawData) { } - public void Import(System.ReadOnlySpan rawData, System.ReadOnlySpan password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } - public void Import(System.ReadOnlySpan rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } - public void Import(string fileName) { } - public void Import(string fileName, System.ReadOnlySpan password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } - public void Import(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } - public void ImportFromPem(System.ReadOnlySpan certPem) { } - public void ImportFromPemFile(string certPemFilePath) { } - public void Insert(int index, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } - public void Remove(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } - public void RemoveRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } - public void RemoveRange(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { } - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } - public bool TryExportCertificatePems(System.Span destination, out int charsWritten) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] - public bool TryExportPkcs7Pem(System.Span destination, out int charsWritten) { throw null; } - } - public sealed partial class X509Certificate2Enumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable - { - internal X509Certificate2Enumerator() { } - public System.Security.Cryptography.X509Certificates.X509Certificate2 Current { get { throw null; } } - object System.Collections.IEnumerator.Current { get { throw null; } } - public bool MoveNext() { throw null; } - public void Reset() { } - bool System.Collections.IEnumerator.MoveNext() { throw null; } - void System.Collections.IEnumerator.Reset() { } - void System.IDisposable.Dispose() { } - } - public partial class X509CertificateCollection : System.Collections.CollectionBase - { - public X509CertificateCollection() { } - public X509CertificateCollection(System.Security.Cryptography.X509Certificates.X509CertificateCollection value) { } - public X509CertificateCollection(System.Security.Cryptography.X509Certificates.X509Certificate[] value) { } - public System.Security.Cryptography.X509Certificates.X509Certificate this[int index] { get { throw null; } set { } } - public int Add(System.Security.Cryptography.X509Certificates.X509Certificate value) { throw null; } - public void AddRange(System.Security.Cryptography.X509Certificates.X509CertificateCollection value) { } - public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate[] value) { } - public bool Contains(System.Security.Cryptography.X509Certificates.X509Certificate value) { throw null; } - public void CopyTo(System.Security.Cryptography.X509Certificates.X509Certificate[] array, int index) { } - public new System.Security.Cryptography.X509Certificates.X509CertificateCollection.X509CertificateEnumerator GetEnumerator() { throw null; } - public override int GetHashCode() { throw null; } - public int IndexOf(System.Security.Cryptography.X509Certificates.X509Certificate value) { throw null; } - public void Insert(int index, System.Security.Cryptography.X509Certificates.X509Certificate value) { } - protected override void OnValidate(object value) { } - public void Remove(System.Security.Cryptography.X509Certificates.X509Certificate value) { } - public partial class X509CertificateEnumerator : System.Collections.IEnumerator - { - public X509CertificateEnumerator(System.Security.Cryptography.X509Certificates.X509CertificateCollection mappings) { } - public System.Security.Cryptography.X509Certificates.X509Certificate Current { get { throw null; } } - object System.Collections.IEnumerator.Current { get { throw null; } } - public bool MoveNext() { throw null; } - public void Reset() { } - bool System.Collections.IEnumerator.MoveNext() { throw null; } - void System.Collections.IEnumerator.Reset() { } - } - } - public partial class X509Chain : System.IDisposable - { - public X509Chain() { } - public X509Chain(bool useMachineContext) { } - [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] - public X509Chain(System.IntPtr chainContext) { } - public System.IntPtr ChainContext { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509ChainElementCollection ChainElements { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509ChainPolicy ChainPolicy { get { throw null; } set { } } - public System.Security.Cryptography.X509Certificates.X509ChainStatus[] ChainStatus { get { throw null; } } - public Microsoft.Win32.SafeHandles.SafeX509ChainHandle? SafeHandle { get { throw null; } } - public bool Build(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509Chain Create() { throw null; } - public void Dispose() { } - protected virtual void Dispose(bool disposing) { } - public void Reset() { } - } - public partial class X509ChainElement - { - internal X509ChainElement() { } - public System.Security.Cryptography.X509Certificates.X509Certificate2 Certificate { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509ChainStatus[] ChainElementStatus { get { throw null; } } - public string Information { get { throw null; } } - } - public sealed partial class X509ChainElementCollection : System.Collections.Generic.IEnumerable, System.Collections.ICollection, System.Collections.IEnumerable - { - internal X509ChainElementCollection() { } - public int Count { get { throw null; } } - public bool IsSynchronized { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509ChainElement this[int index] { get { throw null; } } - public object SyncRoot { get { throw null; } } - public void CopyTo(System.Security.Cryptography.X509Certificates.X509ChainElement[] array, int index) { } - public System.Security.Cryptography.X509Certificates.X509ChainElementEnumerator GetEnumerator() { throw null; } - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } - void System.Collections.ICollection.CopyTo(System.Array array, int index) { } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - public sealed partial class X509ChainElementEnumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable - { - internal X509ChainElementEnumerator() { } - public System.Security.Cryptography.X509Certificates.X509ChainElement Current { get { throw null; } } - object System.Collections.IEnumerator.Current { get { throw null; } } - public bool MoveNext() { throw null; } - public void Reset() { } - void System.IDisposable.Dispose() { } - } - public sealed partial class X509ChainPolicy - { - public X509ChainPolicy() { } - public System.Security.Cryptography.OidCollection ApplicationPolicy { get { throw null; } } - public System.Security.Cryptography.OidCollection CertificatePolicy { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509Certificate2Collection CustomTrustStore { get { throw null; } } - public bool DisableCertificateDownloads { get { throw null; } set { } } - public System.Security.Cryptography.X509Certificates.X509Certificate2Collection ExtraStore { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509RevocationFlag RevocationFlag { get { throw null; } set { } } - public System.Security.Cryptography.X509Certificates.X509RevocationMode RevocationMode { get { throw null; } set { } } - public System.Security.Cryptography.X509Certificates.X509ChainTrustMode TrustMode { get { throw null; } set { } } - public System.TimeSpan UrlRetrievalTimeout { get { throw null; } set { } } - public System.Security.Cryptography.X509Certificates.X509VerificationFlags VerificationFlags { get { throw null; } set { } } - public System.DateTime VerificationTime { get { throw null; } set { } } - public void Reset() { } - } - public partial struct X509ChainStatus - { - private object _dummy; - private int _dummyPrimitive; - public System.Security.Cryptography.X509Certificates.X509ChainStatusFlags Status { readonly get { throw null; } set { } } - [System.Diagnostics.CodeAnalysis.AllowNullAttribute] - public string StatusInformation { get { throw null; } set { } } - } - [System.FlagsAttribute] - public enum X509ChainStatusFlags - { - NoError = 0, - NotTimeValid = 1, - NotTimeNested = 2, - Revoked = 4, - NotSignatureValid = 8, - NotValidForUsage = 16, - UntrustedRoot = 32, - RevocationStatusUnknown = 64, - Cyclic = 128, - InvalidExtension = 256, - InvalidPolicyConstraints = 512, - InvalidBasicConstraints = 1024, - InvalidNameConstraints = 2048, - HasNotSupportedNameConstraint = 4096, - HasNotDefinedNameConstraint = 8192, - HasNotPermittedNameConstraint = 16384, - HasExcludedNameConstraint = 32768, - PartialChain = 65536, - CtlNotTimeValid = 131072, - CtlNotSignatureValid = 262144, - CtlNotValidForUsage = 524288, - HasWeakSignature = 1048576, - OfflineRevocation = 16777216, - NoIssuanceChainPolicy = 33554432, - ExplicitDistrust = 67108864, - HasNotSupportedCriticalExtension = 134217728, - } - public enum X509ChainTrustMode - { - System = 0, - CustomRootTrust = 1, - } - public enum X509ContentType - { - Unknown = 0, - Cert = 1, - SerializedCert = 2, - Pfx = 3, - Pkcs12 = 3, - SerializedStore = 4, - Pkcs7 = 5, - Authenticode = 6, - } - public sealed partial class X509EnhancedKeyUsageExtension : System.Security.Cryptography.X509Certificates.X509Extension - { - public X509EnhancedKeyUsageExtension() { } - public X509EnhancedKeyUsageExtension(System.Security.Cryptography.AsnEncodedData encodedEnhancedKeyUsages, bool critical) { } - public X509EnhancedKeyUsageExtension(System.Security.Cryptography.OidCollection enhancedKeyUsages, bool critical) { } - public System.Security.Cryptography.OidCollection EnhancedKeyUsages { get { throw null; } } - public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } - } - public partial class X509Extension : System.Security.Cryptography.AsnEncodedData - { - protected X509Extension() { } - public X509Extension(System.Security.Cryptography.AsnEncodedData encodedExtension, bool critical) { } - public X509Extension(System.Security.Cryptography.Oid oid, byte[] rawData, bool critical) { } - public X509Extension(System.Security.Cryptography.Oid oid, System.ReadOnlySpan rawData, bool critical) { } - public X509Extension(string oid, byte[] rawData, bool critical) { } - public X509Extension(string oid, System.ReadOnlySpan rawData, bool critical) { } - public bool Critical { get { throw null; } set { } } - public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } - } - public sealed partial class X509ExtensionCollection : System.Collections.Generic.IEnumerable, System.Collections.ICollection, System.Collections.IEnumerable - { - public X509ExtensionCollection() { } - public int Count { get { throw null; } } - public bool IsSynchronized { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509Extension this[int index] { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509Extension? this[string oid] { get { throw null; } } - public object SyncRoot { get { throw null; } } - public int Add(System.Security.Cryptography.X509Certificates.X509Extension extension) { throw null; } - public void CopyTo(System.Security.Cryptography.X509Certificates.X509Extension[] array, int index) { } - public System.Security.Cryptography.X509Certificates.X509ExtensionEnumerator GetEnumerator() { throw null; } - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } - void System.Collections.ICollection.CopyTo(System.Array array, int index) { } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - public sealed partial class X509ExtensionEnumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable - { - internal X509ExtensionEnumerator() { } - public System.Security.Cryptography.X509Certificates.X509Extension Current { get { throw null; } } - object System.Collections.IEnumerator.Current { get { throw null; } } - public bool MoveNext() { throw null; } - public void Reset() { } - void System.IDisposable.Dispose() { } - } - public enum X509FindType - { - FindByThumbprint = 0, - FindBySubjectName = 1, - FindBySubjectDistinguishedName = 2, - FindByIssuerName = 3, - FindByIssuerDistinguishedName = 4, - FindBySerialNumber = 5, - FindByTimeValid = 6, - FindByTimeNotYetValid = 7, - FindByTimeExpired = 8, - FindByTemplateName = 9, - FindByApplicationPolicy = 10, - FindByCertificatePolicy = 11, - FindByExtension = 12, - FindByKeyUsage = 13, - FindBySubjectKeyIdentifier = 14, - } - public enum X509IncludeOption - { - None = 0, - ExcludeRoot = 1, - EndCertOnly = 2, - WholeChain = 3, - } - [System.FlagsAttribute] - public enum X509KeyStorageFlags - { - DefaultKeySet = 0, - UserKeySet = 1, - MachineKeySet = 2, - Exportable = 4, - UserProtected = 8, - PersistKeySet = 16, - EphemeralKeySet = 32, - } - public sealed partial class X509KeyUsageExtension : System.Security.Cryptography.X509Certificates.X509Extension - { - public X509KeyUsageExtension() { } - public X509KeyUsageExtension(System.Security.Cryptography.AsnEncodedData encodedKeyUsage, bool critical) { } - public X509KeyUsageExtension(System.Security.Cryptography.X509Certificates.X509KeyUsageFlags keyUsages, bool critical) { } - public System.Security.Cryptography.X509Certificates.X509KeyUsageFlags KeyUsages { get { throw null; } } - public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } - } - [System.FlagsAttribute] - public enum X509KeyUsageFlags - { - None = 0, - EncipherOnly = 1, - CrlSign = 2, - KeyCertSign = 4, - KeyAgreement = 8, - DataEncipherment = 16, - KeyEncipherment = 32, - NonRepudiation = 64, - DigitalSignature = 128, - DecipherOnly = 32768, - } - public enum X509NameType - { - SimpleName = 0, - EmailName = 1, - UpnName = 2, - DnsName = 3, - DnsFromAlternativeName = 4, - UrlName = 5, - } - public enum X509RevocationFlag - { - EndCertificateOnly = 0, - EntireChain = 1, - ExcludeRoot = 2, - } - public enum X509RevocationMode - { - NoCheck = 0, - Online = 1, - Offline = 2, - } - public abstract partial class X509SignatureGenerator - { - protected X509SignatureGenerator() { } - public System.Security.Cryptography.X509Certificates.PublicKey PublicKey { get { throw null; } } - protected abstract System.Security.Cryptography.X509Certificates.PublicKey BuildPublicKey(); - public static System.Security.Cryptography.X509Certificates.X509SignatureGenerator CreateForECDsa(System.Security.Cryptography.ECDsa key) { throw null; } - public static System.Security.Cryptography.X509Certificates.X509SignatureGenerator CreateForRSA(System.Security.Cryptography.RSA key, System.Security.Cryptography.RSASignaturePadding signaturePadding) { throw null; } - public abstract byte[] GetSignatureAlgorithmIdentifier(System.Security.Cryptography.HashAlgorithmName hashAlgorithm); - public abstract byte[] SignData(byte[] data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm); - } - public sealed partial class X509Store : System.IDisposable - { - public X509Store() { } - public X509Store(System.IntPtr storeHandle) { } - public X509Store(System.Security.Cryptography.X509Certificates.StoreLocation storeLocation) { } - public X509Store(System.Security.Cryptography.X509Certificates.StoreName storeName) { } - public X509Store(System.Security.Cryptography.X509Certificates.StoreName storeName, System.Security.Cryptography.X509Certificates.StoreLocation storeLocation) { } - public X509Store(System.Security.Cryptography.X509Certificates.StoreName storeName, System.Security.Cryptography.X509Certificates.StoreLocation storeLocation, System.Security.Cryptography.X509Certificates.OpenFlags flags) { } - public X509Store(string storeName) { } - public X509Store(string storeName, System.Security.Cryptography.X509Certificates.StoreLocation storeLocation) { } - public X509Store(string storeName, System.Security.Cryptography.X509Certificates.StoreLocation storeLocation, System.Security.Cryptography.X509Certificates.OpenFlags flags) { } - public System.Security.Cryptography.X509Certificates.X509Certificate2Collection Certificates { get { throw null; } } - public bool IsOpen { get { throw null; } } - public System.Security.Cryptography.X509Certificates.StoreLocation Location { get { throw null; } } - public string? Name { get { throw null; } } - public System.IntPtr StoreHandle { get { throw null; } } - public void Add(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } - public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } - public void Close() { } - public void Dispose() { } - public void Open(System.Security.Cryptography.X509Certificates.OpenFlags flags) { } - public void Remove(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } - public void RemoveRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } - } - public sealed partial class X509SubjectKeyIdentifierExtension : System.Security.Cryptography.X509Certificates.X509Extension - { - public X509SubjectKeyIdentifierExtension() { } - public X509SubjectKeyIdentifierExtension(byte[] subjectKeyIdentifier, bool critical) { } - public X509SubjectKeyIdentifierExtension(System.ReadOnlySpan subjectKeyIdentifier, bool critical) { } - public X509SubjectKeyIdentifierExtension(System.Security.Cryptography.AsnEncodedData encodedSubjectKeyIdentifier, bool critical) { } - public X509SubjectKeyIdentifierExtension(System.Security.Cryptography.X509Certificates.PublicKey key, bool critical) { } - public X509SubjectKeyIdentifierExtension(System.Security.Cryptography.X509Certificates.PublicKey key, System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical) { } - public X509SubjectKeyIdentifierExtension(string subjectKeyIdentifier, bool critical) { } - public string? SubjectKeyIdentifier { get { throw null; } } - public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } - } - public enum X509SubjectKeyIdentifierHashAlgorithm - { - Sha1 = 0, - ShortSha1 = 1, - CapiSha1 = 2, - } - [System.FlagsAttribute] - public enum X509VerificationFlags - { - NoFlag = 0, - IgnoreNotTimeValid = 1, - IgnoreCtlNotTimeValid = 2, - IgnoreNotTimeNested = 4, - IgnoreInvalidBasicConstraints = 8, - AllowUnknownCertificateAuthority = 16, - IgnoreWrongUsage = 32, - IgnoreInvalidName = 64, - IgnoreInvalidPolicy = 128, - IgnoreEndRevocationUnknown = 256, - IgnoreCtlSignerRevocationUnknown = 512, - IgnoreCertificateAuthorityRevocationUnknown = 1024, - IgnoreRootRevocationUnknown = 2048, - AllFlags = 4095, - } -} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.csproj b/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.csproj index c3693ce72fe58a..71d56f25038d49 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.csproj +++ b/src/libraries/System.Security.Cryptography.X509Certificates/ref/System.Security.Cryptography.X509Certificates.csproj @@ -5,15 +5,10 @@ $(NoWarn);SYSLIB0026 - + - - - - - diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Helpers.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Helpers.cs deleted file mode 100644 index 731440b7c77261..00000000000000 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Helpers.cs +++ /dev/null @@ -1,350 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Formats.Asn1; -using System.Globalization; -using System.Security.Cryptography; - -namespace Internal.Cryptography -{ - internal static partial class Helpers - { - internal static ReadOnlySpan AsSpanParameter(this byte[] array, string paramName) - { - if (array == null) - throw new ArgumentNullException(paramName); - - return new ReadOnlySpan(array); - } - - // Encode a byte array as an array of upper-case hex characters. - public static char[] ToHexArrayUpper(this byte[] bytes) - { - char[] chars = new char[bytes.Length * 2]; - HexConverter.EncodeToUtf16(bytes, chars); - return chars; - } - - // Encode a byte array as an upper case hex string. - public static string ToHexStringUpper(this byte[] bytes) => - Convert.ToHexString(bytes); - - // Decode a hex string-encoded byte array passed to various X509 crypto api. - // The parsing rules are overly forgiving but for compat reasons, they cannot be tightened. - public static byte[] DecodeHexString(this string hexString) - { - int whitespaceCount = 0; - - ReadOnlySpan s = hexString; - - if (s.Length != 0 && s[0] == '\u200E') - { - s = s.Slice(1); - } - - for (int i = 0; i < s.Length; i++) - { - if (char.IsWhiteSpace(s[i])) - whitespaceCount++; - } - - uint cbHex = (uint)(s.Length - whitespaceCount) / 2; - byte[] hex = new byte[cbHex]; - byte accum = 0; - bool byteInProgress = false; - int index = 0; - - for (int i = 0; i < s.Length; i++) - { - char c = s[i]; - - if (char.IsWhiteSpace(c)) - { - continue; - } - - accum <<= 4; - accum |= (byte)HexConverter.FromChar(c); - - byteInProgress = !byteInProgress; - - // If we've flipped from 0 to 1, back to 0, we have a whole byte - // so add it to the buffer. - if (!byteInProgress) - { - Debug.Assert(index < cbHex, "index < cbHex"); - - hex[index] = accum; - index++; - } - } - - // .NET Framework compat: - // The .NET Framework algorithm removed all whitespace before the loop, then went up to length/2 - // of what was left. This means that in the event of odd-length input the last char is - // ignored, no exception should be raised. - Debug.Assert(index == cbHex, "index == cbHex"); - - return hex; - } - - public static bool ContentsEqual(this byte[]? a1, byte[]? a2) - { - if (a1 == null) - { - return a2 == null; - } - - if (a2 == null || a1.Length != a2.Length) - { - return false; - } - - for (int i = 0; i < a1.Length; i++) - { - if (a1[i] != a2[i]) - { - return false; - } - } - - return true; - } - - internal static void AddRange(this ICollection coll, IEnumerable newData) - { - foreach (T datum in newData) - { - coll.Add(datum); - } - } - - // - // The following group of helpers emulates the non-public Calendar.IsValidDay() method used by X509Certificate.ToString(bool). - // - public static bool IsValidDay(this Calendar calendar, int year, int month, int day, int era) - { - return (calendar.IsValidMonth(year, month, era) && day >= 1 && day <= calendar.GetDaysInMonth(year, month, era)); - } - - private static bool IsValidMonth(this Calendar calendar, int year, int month, int era) - { - return (calendar.IsValidYear(year, era) && month >= 1 && month <= calendar.GetMonthsInYear(year, era)); - } - - private static bool IsValidYear(this Calendar calendar, int year, int era) - { - return (year >= calendar.GetYear(calendar.MinSupportedDateTime) && year <= calendar.GetYear(calendar.MaxSupportedDateTime)); - } - - internal static void DisposeAll(this IEnumerable disposables) - { - foreach (IDisposable disposable in disposables) - { - disposable.Dispose(); - } - } - - public static void ValidateDer(ReadOnlyMemory encodedValue) - { - try - { - Asn1Tag tag; - AsnReader reader = new AsnReader(encodedValue, AsnEncodingRules.DER); - - while (reader.HasData) - { - tag = reader.PeekTag(); - - // If the tag is in the UNIVERSAL class - // - // DER limits the constructed encoding to SEQUENCE and SET, as well as anything which gets - // a defined encoding as being an IMPLICIT SEQUENCE. - if (tag.TagClass == TagClass.Universal) - { - switch ((UniversalTagNumber)tag.TagValue) - { - case UniversalTagNumber.External: - case UniversalTagNumber.Embedded: - case UniversalTagNumber.Sequence: - case UniversalTagNumber.Set: - case UniversalTagNumber.UnrestrictedCharacterString: - if (!tag.IsConstructed) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - break; - default: - if (tag.IsConstructed) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - break; - } - } - - if (tag.IsConstructed) - { - ValidateDer(reader.PeekContentBytes()); - } - - // Skip past the current value. - reader.ReadEncodedValue(); - } - } - catch (AsnContentException e) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); - } - } - - public static ReadOnlyMemory DecodeOctetStringAsMemory(ReadOnlyMemory encodedOctetString) - { - try - { - ReadOnlySpan input = encodedOctetString.Span; - - if (AsnDecoder.TryReadPrimitiveOctetString( - input, - AsnEncodingRules.BER, - out ReadOnlySpan primitive, - out int consumed)) - { - if (consumed != input.Length) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - if (input.Overlaps(primitive, out int offset)) - { - return encodedOctetString.Slice(offset, primitive.Length); - } - - Debug.Fail("input.Overlaps(primitive) failed after TryReadPrimitiveOctetString succeeded"); - } - - byte[] ret = AsnDecoder.ReadOctetString(input, AsnEncodingRules.BER, out consumed); - - if (consumed != input.Length) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - return ret; - } - catch (AsnContentException e) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); - } - } - - public static bool AreSamePublicECParameters(ECParameters aParameters, ECParameters bParameters) - { - if (aParameters.Curve.CurveType != bParameters.Curve.CurveType) - return false; - - if (!aParameters.Q.X!.ContentsEqual(bParameters.Q.X!) || - !aParameters.Q.Y!.ContentsEqual(bParameters.Q.Y!)) - { - return false; - } - - ECCurve aCurve = aParameters.Curve; - ECCurve bCurve = bParameters.Curve; - - if (aCurve.IsNamed) - { - // On Windows we care about FriendlyName, on Unix we care about Value - return (aCurve.Oid.Value == bCurve.Oid.Value && aCurve.Oid.FriendlyName == bCurve.Oid.FriendlyName); - } - - if (!aCurve.IsExplicit) - { - // Implicit curve, always fail. - return false; - } - - // Ignore Cofactor (which is derivable from the prime or polynomial and Order) - // Ignore Seed and Hash (which are entirely optional, and about how A and B were built) - if (!aCurve.G.X!.ContentsEqual(bCurve.G.X!) || - !aCurve.G.Y!.ContentsEqual(bCurve.G.Y!) || - !aCurve.Order.ContentsEqual(bCurve.Order) || - !aCurve.A.ContentsEqual(bCurve.A) || - !aCurve.B.ContentsEqual(bCurve.B)) - { - return false; - } - - if (aCurve.IsPrime) - { - return aCurve.Prime.ContentsEqual(bCurve.Prime); - } - - if (aCurve.IsCharacteristic2) - { - return aCurve.Polynomial.ContentsEqual(bCurve.Polynomial); - } - - Debug.Fail($"Missing match criteria for curve type {aCurve.CurveType}"); - return false; - } - } - - internal static class DictionaryStringHelper - { - internal static string ReadAnyAsnString(this AsnReader tavReader) - { - Asn1Tag tag = tavReader.PeekTag(); - - if (tag.TagClass != TagClass.Universal) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - - switch ((UniversalTagNumber)tag.TagValue) - { - case UniversalTagNumber.BMPString: - case UniversalTagNumber.IA5String: - case UniversalTagNumber.NumericString: - case UniversalTagNumber.PrintableString: - case UniversalTagNumber.UTF8String: - case UniversalTagNumber.T61String: - // .NET's string comparisons start by checking the length, so a trailing - // NULL character which was literally embedded in the DER would cause a - // failure in .NET whereas it wouldn't have with strcmp. - return tavReader.ReadCharacterString((UniversalTagNumber)tag.TagValue).TrimEnd('\0'); - - default: - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); - } - } - } - - internal struct PinAndClear : IDisposable - { - private byte[] _data; - private System.Runtime.InteropServices.GCHandle _gcHandle; - - internal static PinAndClear Track(byte[] data) - { - return new PinAndClear - { - _gcHandle = System.Runtime.InteropServices.GCHandle.Alloc( - data, - System.Runtime.InteropServices.GCHandleType.Pinned), - _data = data, - }; - } - - public void Dispose() - { - Array.Clear(_data); - _gcHandle.Free(); - } - } -} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/CertificatePal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/CertificatePal.cs deleted file mode 100644 index 3b78e65f5eeed6..00000000000000 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/CertificatePal.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using Microsoft.Win32.SafeHandles; - -namespace Internal.Cryptography.Pal -{ - internal sealed partial class CertificatePal - { - public static ICertificatePal FromHandle(IntPtr handle) - { - return AndroidCertificatePal.FromHandle(handle); - } - - public static ICertificatePal FromOtherCert(X509Certificate cert) - { - return AndroidCertificatePal.FromOtherCert(cert); - } - - public static ICertificatePal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) - { - return AndroidCertificatePal.FromBlob(rawData, password, keyStorageFlags); - } - - public static ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) - { - return AndroidCertificatePal.FromFile(fileName, password, keyStorageFlags); - } - } -} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/CertificatePal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/CertificatePal.cs deleted file mode 100644 index 0689088c77f52b..00000000000000 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/CertificatePal.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using Microsoft.Win32.SafeHandles; - -namespace Internal.Cryptography.Pal -{ - internal sealed partial class CertificatePal - { - public static ICertificatePal? FromHandle(IntPtr handle) - { - return FromHandle(handle, true); - } - - internal static ICertificatePal? FromHandle(IntPtr handle, bool throwOnFail) - { - return AppleCertificatePal.FromHandle(handle, throwOnFail); - } - - public static ICertificatePal? FromOtherCert(X509Certificate cert) - { - return AppleCertificatePal.FromOtherCert(cert); - } - - public static ICertificatePal FromBlob( - ReadOnlySpan rawData, - SafePasswordHandle password, - X509KeyStorageFlags keyStorageFlags) - { - return AppleCertificatePal.FromBlob(rawData, password, keyStorageFlags); - } - - public static ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) - { - return AppleCertificatePal.FromFile(fileName, password, keyStorageFlags); - } - } -} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePal.cs deleted file mode 100644 index a7bfa16005f4d0..00000000000000 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePal.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -using Microsoft.Win32.SafeHandles; - -namespace Internal.Cryptography.Pal -{ - internal sealed partial class CertificatePal - { - public static ICertificatePal FromHandle(IntPtr handle) - { - return OpenSslX509CertificateReader.FromHandle(handle); - } - - public static ICertificatePal FromOtherCert(X509Certificate cert) - { - return OpenSslX509CertificateReader.FromOtherCert(cert); - } - - public static ICertificatePal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) - { - return OpenSslX509CertificateReader.FromBlob(rawData, password, keyStorageFlags); - } - - public static ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) - { - return OpenSslX509CertificateReader.FromFile(fileName, password, keyStorageFlags); - } - } -} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/FindPal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/FindPal.cs deleted file mode 100644 index a15bf1b5abdd29..00000000000000 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/FindPal.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Security.Cryptography.X509Certificates; - -namespace Internal.Cryptography.Pal -{ - internal sealed partial class FindPal - { - internal static IFindPal OpenPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) - { - return new OpenSslCertificateFinder(findFrom, copyTo, validOnly); - } - } -} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.cs deleted file mode 100644 index 69c26d410e975f..00000000000000 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Text; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.InteropServices; - -using Internal.Cryptography; -using Internal.Cryptography.Pal.Native; - -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; - -namespace Internal.Cryptography.Pal -{ - /// - /// A singleton class that encapsulates the native implementation of various X509 services. (Implementing this as a singleton makes it - /// easier to split the class into abstract and implementation classes if desired.) - /// - internal sealed partial class X509Pal : IX509Pal - { - public static IX509Pal Instance = new X509Pal(); - - private X509Pal() - { - } - } -} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx deleted file mode 100644 index 43328cc42ac286..00000000000000 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx +++ /dev/null @@ -1,451 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Error occurred during a cryptographic operation. - - - Array may not be empty or null. - - - String cannot be empty or null. - - - The '{0}' string cannot be empty or null. - - - Illegal enum value: {0}. - - - Invalid handle. - - - Invalid type. - - - Non-negative number required. - - - Only single dimensional arrays are supported for the requested action. - - - The destination is too small to hold the encoded value. - - - Value of flags is invalid. - - - The value of 'nameType' is invalid. - - - Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. - - - The OID value was invalid. - - - Index was out of range. Must be non-negative and less than the size of the collection. - - - An empty custom trust store is not supported on this platform. - - - The certificate has invalid policy. - - - The certificate chain is incomplete. - - - The certificate's revocation status could not be determined. - - - The provided value of {0} bytes does not match the expected size of {1} bytes for the algorithm ({2}). - - - The certificate already has an associated private key. - - - The issuer certificate public key algorithm ({0}) does not match the value for this certificate request ({1}), use the X509SignatureGenerator overload. - - - The issuer certificate does not have a Basic Constraints extension. - - - The provided notBefore value is later than the notAfter value. - - - An X509Extension with OID '{0}' has already been specified. - - - The issuer certificate does not have an appropriate value for the Basic Constraints extension. - - - The issuer certificate's Key Usage extension is present but does not contain the KeyCertSign flag. - - - The provided issuer certificate does not have an associated private key. - - - The requested notAfter value ({0}) is later than issuerCertificate.NotAfter ({1}). - - - The requested notBefore value ({0}) is earlier than issuerCertificate.NotBefore ({1}). - - - This method cannot be used since no signing key was provided via a constructor, use an overload accepting an X509SignatureGenerator instead. - - - The issuer certificate uses an RSA key but no RSASignaturePadding was provided to a constructor. If one cannot be provided, use the X509SignatureGenerator overload. - - - Object contains only the public half of a key pair. A private key must also be provided. - - - The specified curve '{0}' or its parameters are not valid for this platform. - - - Only named curves are supported on this platform. - - - The message exceeds the maximum allowable length for the chosen options ({0}). - - - ASN1 corrupted data. - - - The specified Characteristic2 curve parameters are not valid. Polynomial, A, B, G.X, G.Y, and Order are required. A, B, G.X, G.Y must be the same length, and the same length as Q.X, Q.Y and D if those are specified. Seed, Cofactor and Hash are optional. Other parameters are not allowed. - - - The chain context handle is invalid. - - - {0} is an invalid handle. - - - Object identifier (OID) is unknown. - - - Specified padding mode is not valid for this algorithm. - - - The specified RSA parameters are not valid. Exponent and Modulus are required. If D is present, it must have the same length as Modulus. If D is present, P, Q, DP, DQ, and InverseQ are required and must have half the length of Modulus, rounded up, otherwise they must be omitted. - - - The store handle is invalid. - - - Custom trust certificates were provided while in System trust mode. - - - A null or disposed certificate was present in CustomTrustStore. - - - The key is too small for the requested operation. - - - Error occurred while decoding OAEP padding. - - - Cannot open an invalid handle. - - - A certificate referenced a private key which was already referenced, or could not be loaded. - - - The certificate data cannot be read with the provided password, the password may be incorrect. - - - The provided PFX data contains no certificates. - - - The provided key does not match the public key for this certificate. - - - The provided key does not match the public key algorithm for this certificate. - - - The length of the data to decrypt is not valid for the size of this key. - - - The provided hash value is not the expected size for the specified hash algorithm. - - - The Disallowed store is not supported on this platform, but already has data. All files under '{0}' must be removed. - - - Unix LocalMachine X509Stores are read-only for all users. - - - Unix LocalMachine X509Store is limited to the Root and CertificateAuthority stores. - - - The Disallowed store is not supported on this platform. - - - The {0} value cannot be set on Unix. - - - '{0}' is not a known hash algorithm. - - - '{0}' is not a known key algorithm. - - - The signature format '{0}' is unknown. - - - X509ContentType.SerializedCert and X509ContentType.SerializedStore are not supported on Unix. - - - The system cryptographic library returned error '{0}' of type '{1}' - - - The certificate export operation failed. - - - The parameter should be an X509Extension. - - - Invalid content type. - - - Invalid find type. - - - Invalid find value. - - - The flags '{0}' may not be specified together. - - - Cannot find the original signer. - - - PKCS#7 certificate format is not supported on this platform. - - - The PKCS#12 PersistKeySet flag is not supported on this platform. - - - The PKCS#12 Exportable flag is not supported on this platform. - - - The X509 certificate could not be added to the store. - - - The X509 certificate could not be added to the store because all candidate file names were in use. - - - The specified X509 certificate store does not exist. - - - The X509 certificate store has not been opened. - - - The X509 certificate store is read-only. - - - The X509 certificate could not be removed from the store. - - - The platform does not have a definition for an X509 certificate store named '{0}' with a StoreLocation of '{1}', and does not support creating it. - - - Adding a DSA private key to the store is not supported on this platform. - - - Failed to enumerate certificates from the store. - - - Root certificate store is not supported on this platform. - - - The certificate contents do not contain a PEM with a CERTIFICATE label, or the content is malformed. - - - The key contents do not contain a PEM, the content is malformed, or the key does not match the certificate. - - - Certificate '{0}' is corrupted. - - - Enumeration has not started. Call MoveNext. - - - CryptoApi ECDsa keys are not supported. - - - CryptoApi ECDiffieHellman keys are not supported. - - - The certificate key algorithm is not supported. - - - The X509 Basic Constraints extension with OID 2.5.29.10 is not supported. - - - X509Certificate is immutable on this platform. Use the equivalent constructor instead. - - - The home directory of the current user could not be determined. - - - The {0} value was invalid. - - - Access is denied. - - - Unknown error. - - - Algorithm '{0}' is not supported on this platform. - - - Unable to get file status. - - - Invalid directory permissions. The directory '{0}' must be readable, writable and executable by the owner. - - - The owner of '{0}' is not the current user. - - - Invalid file permissions. The file '{0}' must readable and writable by the current owner and by no one else, and the permissions could not be changed to meet that criteria. - - - The string contains an invalid X500 name attribute key, oid, value or delimiter. - - - The string contains a character not in the 7 bit ASCII character set. - - - This platform does not support loading with EphemeralKeySet. Remove the flag to allow keys to be temporarily created on disk. - - - Removing the requested certificate would modify user trust settings, and has been denied. - - - Removing the requested certificate would modify admin trust settings, and has been denied. - - - Specified key is not a valid size for this algorithm. - - - DSA keys can be imported, but new key generation is not supported on this platform. - - - The specified DSA parameters are not valid; P, Q, G and Y are all required. - - - The specified DSA parameters are not valid; P, G and Y must be the same length (the key size). - - - The specified DSA parameters are not valid; Q and X (if present) must be the same length. - - - The specified DSA parameters are not valid; J (if present) must be shorter than P. - - - The specified DSA parameters are not valid; Seed, if present, must be 20 bytes long for keys shorter than 1024 bits. - - - The specified DSA parameters are not valid; Q must be 20 bytes long for keys shorter than 1024 bits. - - - The specified DSA parameters are not valid; Q's length must be one of 20, 32 or 64 bytes. - - - Key is not a valid public or private key. - - - The EncryptedPrivateKeyInfo structure was decoded but was not successfully interpreted, the password may be incorrect. - - - The algorithm identified by '{0}' is unknown, not valid for the requested usage, or was not handled. - - - Value was invalid. - - - The KDF for algorithm '{0}' requires a char-based password input. - - - The provided RSAPrivateKey value has version '{0}', but version '{1}' is the maximum supported. - - - Key is not a valid private key. - - - System.Security.Cryptography.X509Certificates is not supported on this platform. - - - The keys from both parties must be the same size to generate a secret agreement. - - - Keys used with the ECDiffieHellmanCng algorithm must have an algorithm group of ECDiffieHellman. - - - The TLS key derivation function requires a seed value of exactly 64 bytes. - - - The certificate content type could not be determined. - - diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj b/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj index 3ea6525c02b418..1fe031a388f591 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj @@ -1,993 +1,10 @@ - true - $(NoWarn);CA5384 - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent) - enable + $(NetCoreAppCurrent) + true - - $(NoWarn);CS8769;SYSLIB0026 - SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported - - - true - true - - - - - - - - - - - - - - - - - - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml - - - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml.cs - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml - - - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.manual.cs - Common\System\Security\Cryptography\Asn1\AlgorithmIdentifierAsn.xml - - - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml - - - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml.cs - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml - - - Common\System\Security\Cryptography\Asn1\AttributeAsn.manual.cs - Common\System\Security\Cryptography\Asn1\AttributeAsn.xml - - - Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml - - - Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml.cs - Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml - - - Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml - - - Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml.cs - Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml - - - Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml - - - Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml.cs - Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml - - - Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml - - - Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml.cs - Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml - - - Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml - - - Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml.cs - Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml - - - Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.xml - - - Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.xml.cs - Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.xml - - - Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.manual.cs - Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - System\Security\Cryptography\X509Certificates\Asn1\BasicConstraintsAsn.xml - - - - System\Security\Cryptography\X509Certificates\Asn1\CertificateAsn.xml - - - - System\Security\Cryptography\X509Certificates\Asn1\CertificationRequestAsn.xml - - - - System\Security\Cryptography\X509Certificates\Asn1\CertificationRequestInfoAsn.xml - - - - - System\Security\Cryptography\X509Certificates\Asn1\TbsCertificateAsn.xml - - - - - System\Security\Cryptography\X509Certificates\Asn1\TimeAsn.xml - - - - - System\Security\Cryptography\X509Certificates\Asn1\ValidityAsn.xml - - - - - System\Security\Cryptography\X509Certificates\Asn1\AccessDescriptionAsn.xml - - - - System\Security\Cryptography\X509Certificates\Asn1\CertificatePolicyMappingAsn.xml - - - - System\Security\Cryptography\X509Certificates\Asn1\CertificateTemplateAsn.xml - - - - System\Security\Cryptography\X509Certificates\Asn1\PolicyConstraintsAsn.xml - - - - System\Security\Cryptography\X509Certificates\Asn1\PolicyInformationAsn.xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - System\Security\Cryptography\X509Certificates\Asn1\DistributionPointAsn.xml - - - - System\Security\Cryptography\X509Certificates\Asn1\DistributionPointNameAsn.xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Common\System\Security\Cryptography\Asn1\CurveAsn.xml - - - Common\System\Security\Cryptography\Asn1\CurveAsn.xml.cs - Common\System\Security\Cryptography\Asn1\CurveAsn.xml - - - Common\System\Security\Cryptography\Asn1\DssParms.xml - - - Common\System\Security\Cryptography\Asn1\DssParms.xml.cs - Common\System\Security\Cryptography\Asn1\DssParms.xml - - - Common\System\Security\Cryptography\Asn1\ECDomainParameters.xml - - - Common\System\Security\Cryptography\Asn1\ECDomainParameters.xml.cs - Common\System\Security\Cryptography\Asn1\ECDomainParameters.xml - - - Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml - - - Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml.cs - Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml - - - Common\System\Security\Cryptography\Asn1\FieldID.xml - - - Common\System\Security\Cryptography\Asn1\FieldID.xml.cs - Common\System\Security\Cryptography\Asn1\FieldID.xml - - - Common\System\Security\Cryptography\Asn1\RSAPrivateKeyAsn.xml - - - Common\System\Security\Cryptography\Asn1\RSAPrivateKeyAsn.xml.cs - Common\System\Security\Cryptography\Asn1\RSAPrivateKeyAsn.xml - - - Common\System\Security\Cryptography\Asn1\RSAPublicKeyAsn.xml - - - Common\System\Security\Cryptography\Asn1\RSAPublicKeyAsn.xml.cs - Common\System\Security\Cryptography\Asn1\RSAPublicKeyAsn.xml - - - Common\System\Security\Cryptography\Asn1\SpecifiedECDomain.xml - - - Common\System\Security\Cryptography\Asn1\SpecifiedECDomain.xml.cs - Common\System\Security\Cryptography\Asn1\SpecifiedECDomain.xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml.cs - Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml.cs - Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.manual.cs - Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml.cs - Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml.cs - Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\PBEParameter.xml - - - Common\System\Security\Cryptography\Asn1\PBEParameter.xml.cs - Common\System\Security\Cryptography\Asn1\PBEParameter.xml - - - Common\System\Security\Cryptography\Asn1\PBES2Params.xml - - - Common\System\Security\Cryptography\Asn1\PBES2Params.xml.cs - Common\System\Security\Cryptography\Asn1\PBES2Params.xml - - - Common\System\Security\Cryptography\Asn1\Pbkdf2Params.xml - - - Common\System\Security\Cryptography\Asn1\Pbkdf2Params.xml.cs - Common\System\Security\Cryptography\Asn1\Pbkdf2Params.xml - - - Common\System\Security\Cryptography\Asn1\Pbkdf2SaltChoice.xml - - - Common\System\Security\Cryptography\Asn1\Pbkdf2SaltChoice.xml.cs - Common\System\Security\Cryptography\Asn1\Pbkdf2SaltChoice.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml - - - Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml.cs - Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml - - - Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml.cs - Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml - - - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml - - - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml.cs - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml - - - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.manual.cs - Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs index 7c32c3cd7dccfe..0976cba08b743f 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs @@ -15,7 +15,7 @@ namespace System.Security.Cryptography.X509Certificates.Tests.RevocationTests public static partial class DynamicRevocationTests { // The CI machines are doing an awful lot of things at once, be generous with the timeout; - internal static readonly TimeSpan s_urlRetrievalLimit = TimeSpan.FromSeconds(15); + internal static readonly TimeSpan s_urlRetrievalLimit = TimeSpan.FromSeconds(30); private static readonly Oid s_tlsServerOid = new Oid("1.3.6.1.5.5.7.3.1", null); diff --git a/src/libraries/System.Security.Cryptography.Xml/NuGet.config b/src/libraries/System.Security.Cryptography.Xml/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Security.Cryptography.Xml/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index e671b178a816b0..e07748b754ef9e 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -4,6 +4,44 @@ // Changes to this file must follow the https://aka.ms/api-review process. // ------------------------------------------------------------------------------ +namespace Microsoft.Win32.SafeHandles +{ + public abstract partial class SafeNCryptHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + protected SafeNCryptHandle() : base (default(bool)) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + protected SafeNCryptHandle(System.IntPtr handle, System.Runtime.InteropServices.SafeHandle parentHandle) : base (default(bool)) { } + protected override bool ReleaseHandle() { throw null; } + protected abstract bool ReleaseNativeHandle(); + } + public sealed partial class SafeNCryptKeyHandle : Microsoft.Win32.SafeHandles.SafeNCryptHandle + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public SafeNCryptKeyHandle() { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public SafeNCryptKeyHandle(System.IntPtr handle, System.Runtime.InteropServices.SafeHandle parentHandle) { } + protected override bool ReleaseNativeHandle() { throw null; } + } + public sealed partial class SafeNCryptProviderHandle : Microsoft.Win32.SafeHandles.SafeNCryptHandle + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public SafeNCryptProviderHandle() { } + protected override bool ReleaseNativeHandle() { throw null; } + } + public sealed partial class SafeNCryptSecretHandle : Microsoft.Win32.SafeHandles.SafeNCryptHandle + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public SafeNCryptSecretHandle() { } + protected override bool ReleaseNativeHandle() { throw null; } + } + public sealed partial class SafeX509ChainHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid + { + public SafeX509ChainHandle() : base (default(bool)) { } + protected override void Dispose(bool disposing) { } + protected override bool ReleaseHandle() { throw null; } + } +} namespace System.Security.Cryptography { public abstract partial class Aes : System.Security.Cryptography.SymmetricAlgorithm @@ -30,6 +68,55 @@ public void Dispose() { } public void Encrypt(byte[] nonce, byte[] plaintext, byte[] ciphertext, byte[] tag, byte[]? associatedData = null) { } public void Encrypt(System.ReadOnlySpan nonce, System.ReadOnlySpan plaintext, System.Span ciphertext, System.Span tag, System.ReadOnlySpan associatedData = default(System.ReadOnlySpan)) { } } + public sealed partial class AesCng : System.Security.Cryptography.Aes + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public AesCng() { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public AesCng(string keyName) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public AesCng(string keyName, System.Security.Cryptography.CngProvider provider) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public AesCng(string keyName, System.Security.Cryptography.CngProvider provider, System.Security.Cryptography.CngKeyOpenOptions openOptions) { } + public override byte[] Key { get { throw null; } set { } } + public override int KeySize { get { throw null; } set { } } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + protected override void Dispose(bool disposing) { } + public override void GenerateIV() { } + public override void GenerateKey() { } + protected override bool TryDecryptCbcCore(System.ReadOnlySpan ciphertext, System.ReadOnlySpan iv, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, out int bytesWritten) { throw null; } + protected override bool TryDecryptCfbCore(System.ReadOnlySpan ciphertext, System.ReadOnlySpan iv, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, int feedbackSizeInBits, out int bytesWritten) { throw null; } + protected override bool TryDecryptEcbCore(System.ReadOnlySpan ciphertext, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, out int bytesWritten) { throw null; } + protected override bool TryEncryptCbcCore(System.ReadOnlySpan plaintext, System.ReadOnlySpan iv, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, out int bytesWritten) { throw null; } + protected override bool TryEncryptCfbCore(System.ReadOnlySpan plaintext, System.ReadOnlySpan iv, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, int feedbackSizeInBits, out int bytesWritten) { throw null; } + protected override bool TryEncryptEcbCore(System.ReadOnlySpan plaintext, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, out int bytesWritten) { throw null; } + } + [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class AesCryptoServiceProvider : System.Security.Cryptography.Aes + { + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public AesCryptoServiceProvider() { } + public override int BlockSize { get { throw null; } set { } } + public override int FeedbackSize { get { throw null; } set { } } + public override byte[] IV { get { throw null; } set { } } + public override byte[] Key { get { throw null; } set { } } + public override int KeySize { get { throw null; } set { } } + public override System.Security.Cryptography.KeySizes[] LegalBlockSizes { get { throw null; } } + public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } + public override System.Security.Cryptography.CipherMode Mode { get { throw null; } set { } } + public override System.Security.Cryptography.PaddingMode Padding { get { throw null; } set { } } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + protected override void Dispose(bool disposing) { } + public override void GenerateIV() { } + public override void GenerateKey() { } + } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] @@ -202,6 +289,223 @@ public enum CipherMode CFB = 4, CTS = 5, } + public sealed partial class CngAlgorithm : System.IEquatable + { + public CngAlgorithm(string algorithm) { } + public string Algorithm { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm ECDiffieHellman { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm ECDiffieHellmanP256 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm ECDiffieHellmanP384 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm ECDiffieHellmanP521 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm ECDsa { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm ECDsaP256 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm ECDsaP384 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm ECDsaP521 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm MD5 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm Rsa { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm Sha1 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm Sha256 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm Sha384 { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithm Sha512 { get { throw null; } } + public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } + public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngAlgorithm? other) { throw null; } + public override int GetHashCode() { throw null; } + public static bool operator ==(System.Security.Cryptography.CngAlgorithm? left, System.Security.Cryptography.CngAlgorithm? right) { throw null; } + public static bool operator !=(System.Security.Cryptography.CngAlgorithm? left, System.Security.Cryptography.CngAlgorithm? right) { throw null; } + public override string ToString() { throw null; } + } + public sealed partial class CngAlgorithmGroup : System.IEquatable + { + public CngAlgorithmGroup(string algorithmGroup) { } + public string AlgorithmGroup { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithmGroup DiffieHellman { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithmGroup Dsa { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithmGroup ECDiffieHellman { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithmGroup ECDsa { get { throw null; } } + public static System.Security.Cryptography.CngAlgorithmGroup Rsa { get { throw null; } } + public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } + public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngAlgorithmGroup? other) { throw null; } + public override int GetHashCode() { throw null; } + public static bool operator ==(System.Security.Cryptography.CngAlgorithmGroup? left, System.Security.Cryptography.CngAlgorithmGroup? right) { throw null; } + public static bool operator !=(System.Security.Cryptography.CngAlgorithmGroup? left, System.Security.Cryptography.CngAlgorithmGroup? right) { throw null; } + public override string ToString() { throw null; } + } + [System.FlagsAttribute] + public enum CngExportPolicies + { + None = 0, + AllowExport = 1, + AllowPlaintextExport = 2, + AllowArchiving = 4, + AllowPlaintextArchiving = 8, + } + public sealed partial class CngKey : System.IDisposable + { + internal CngKey() { } + public System.Security.Cryptography.CngAlgorithm Algorithm { get { throw null; } } + public System.Security.Cryptography.CngAlgorithmGroup? AlgorithmGroup { get { throw null; } } + public System.Security.Cryptography.CngExportPolicies ExportPolicy { get { throw null; } } + public Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle Handle { get { throw null; } } + public bool IsEphemeral { get { throw null; } } + public bool IsMachineKey { get { throw null; } } + public string? KeyName { get { throw null; } } + public int KeySize { get { throw null; } } + public System.Security.Cryptography.CngKeyUsages KeyUsage { get { throw null; } } + public System.IntPtr ParentWindowHandle { get { throw null; } set { } } + public System.Security.Cryptography.CngProvider? Provider { get { throw null; } } + public Microsoft.Win32.SafeHandles.SafeNCryptProviderHandle ProviderHandle { get { throw null; } } + public System.Security.Cryptography.CngUIPolicy UIPolicy { get { throw null; } } + public string? UniqueName { get { throw null; } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.CngKey Create(System.Security.Cryptography.CngAlgorithm algorithm) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.CngKey Create(System.Security.Cryptography.CngAlgorithm algorithm, string? keyName) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.CngKey Create(System.Security.Cryptography.CngAlgorithm algorithm, string? keyName, System.Security.Cryptography.CngKeyCreationParameters? creationParameters) { throw null; } + public void Delete() { } + public void Dispose() { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static bool Exists(string keyName) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static bool Exists(string keyName, System.Security.Cryptography.CngProvider provider) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static bool Exists(string keyName, System.Security.Cryptography.CngProvider provider, System.Security.Cryptography.CngKeyOpenOptions options) { throw null; } + public byte[] Export(System.Security.Cryptography.CngKeyBlobFormat format) { throw null; } + public System.Security.Cryptography.CngProperty GetProperty(string name, System.Security.Cryptography.CngPropertyOptions options) { throw null; } + public bool HasProperty(string name, System.Security.Cryptography.CngPropertyOptions options) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.CngKey Import(byte[] keyBlob, System.Security.Cryptography.CngKeyBlobFormat format) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.CngKey Import(byte[] keyBlob, System.Security.Cryptography.CngKeyBlobFormat format, System.Security.Cryptography.CngProvider provider) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.CngKey Open(Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle keyHandle, System.Security.Cryptography.CngKeyHandleOpenOptions keyHandleOpenOptions) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.CngKey Open(string keyName) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.CngKey Open(string keyName, System.Security.Cryptography.CngProvider provider) { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.CngKey Open(string keyName, System.Security.Cryptography.CngProvider provider, System.Security.Cryptography.CngKeyOpenOptions openOptions) { throw null; } + public void SetProperty(System.Security.Cryptography.CngProperty property) { } + } + public sealed partial class CngKeyBlobFormat : System.IEquatable + { + public CngKeyBlobFormat(string format) { } + public static System.Security.Cryptography.CngKeyBlobFormat EccFullPrivateBlob { get { throw null; } } + public static System.Security.Cryptography.CngKeyBlobFormat EccFullPublicBlob { get { throw null; } } + public static System.Security.Cryptography.CngKeyBlobFormat EccPrivateBlob { get { throw null; } } + public static System.Security.Cryptography.CngKeyBlobFormat EccPublicBlob { get { throw null; } } + public string Format { get { throw null; } } + public static System.Security.Cryptography.CngKeyBlobFormat GenericPrivateBlob { get { throw null; } } + public static System.Security.Cryptography.CngKeyBlobFormat GenericPublicBlob { get { throw null; } } + public static System.Security.Cryptography.CngKeyBlobFormat OpaqueTransportBlob { get { throw null; } } + public static System.Security.Cryptography.CngKeyBlobFormat Pkcs8PrivateBlob { get { throw null; } } + public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } + public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngKeyBlobFormat? other) { throw null; } + public override int GetHashCode() { throw null; } + public static bool operator ==(System.Security.Cryptography.CngKeyBlobFormat? left, System.Security.Cryptography.CngKeyBlobFormat? right) { throw null; } + public static bool operator !=(System.Security.Cryptography.CngKeyBlobFormat? left, System.Security.Cryptography.CngKeyBlobFormat? right) { throw null; } + public override string ToString() { throw null; } + } + [System.FlagsAttribute] + public enum CngKeyCreationOptions + { + None = 0, + MachineKey = 32, + OverwriteExistingKey = 128, + } + public sealed partial class CngKeyCreationParameters + { + public CngKeyCreationParameters() { } + public System.Security.Cryptography.CngExportPolicies? ExportPolicy { get { throw null; } set { } } + public System.Security.Cryptography.CngKeyCreationOptions KeyCreationOptions { get { throw null; } set { } } + public System.Security.Cryptography.CngKeyUsages? KeyUsage { get { throw null; } set { } } + public System.Security.Cryptography.CngPropertyCollection Parameters { get { throw null; } } + public System.IntPtr ParentWindowHandle { get { throw null; } set { } } + public System.Security.Cryptography.CngProvider Provider { get { throw null; } set { } } + public System.Security.Cryptography.CngUIPolicy? UIPolicy { get { throw null; } set { } } + } + [System.FlagsAttribute] + public enum CngKeyHandleOpenOptions + { + None = 0, + EphemeralKey = 1, + } + [System.FlagsAttribute] + public enum CngKeyOpenOptions + { + None = 0, + UserKey = 0, + MachineKey = 32, + Silent = 64, + } + [System.FlagsAttribute] + public enum CngKeyUsages + { + None = 0, + Decryption = 1, + Signing = 2, + KeyAgreement = 4, + AllUsages = 16777215, + } + public partial struct CngProperty : System.IEquatable + { + private object _dummy; + private int _dummyPrimitive; + public CngProperty(string name, byte[]? value, System.Security.Cryptography.CngPropertyOptions options) { throw null; } + public readonly string Name { get { throw null; } } + public readonly System.Security.Cryptography.CngPropertyOptions Options { get { throw null; } } + public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } + public bool Equals(System.Security.Cryptography.CngProperty other) { throw null; } + public override int GetHashCode() { throw null; } + public byte[]? GetValue() { throw null; } + public static bool operator ==(System.Security.Cryptography.CngProperty left, System.Security.Cryptography.CngProperty right) { throw null; } + public static bool operator !=(System.Security.Cryptography.CngProperty left, System.Security.Cryptography.CngProperty right) { throw null; } + } + public sealed partial class CngPropertyCollection : System.Collections.ObjectModel.Collection + { + public CngPropertyCollection() { } + } + [System.FlagsAttribute] + public enum CngPropertyOptions + { + Persist = -2147483648, + None = 0, + CustomProperty = 1073741824, + } + public sealed partial class CngProvider : System.IEquatable + { + public CngProvider(string provider) { } + public static System.Security.Cryptography.CngProvider MicrosoftPlatformCryptoProvider { get { throw null; } } + public static System.Security.Cryptography.CngProvider MicrosoftSmartCardKeyStorageProvider { get { throw null; } } + public static System.Security.Cryptography.CngProvider MicrosoftSoftwareKeyStorageProvider { get { throw null; } } + public string Provider { get { throw null; } } + public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } + public bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.CngProvider? other) { throw null; } + public override int GetHashCode() { throw null; } + public static bool operator ==(System.Security.Cryptography.CngProvider? left, System.Security.Cryptography.CngProvider? right) { throw null; } + public static bool operator !=(System.Security.Cryptography.CngProvider? left, System.Security.Cryptography.CngProvider? right) { throw null; } + public override string ToString() { throw null; } + } + public sealed partial class CngUIPolicy + { + public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel) { } + public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel, string? friendlyName) { } + public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel, string? friendlyName, string? description) { } + public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel, string? friendlyName, string? description, string? useContext) { } + public CngUIPolicy(System.Security.Cryptography.CngUIProtectionLevels protectionLevel, string? friendlyName, string? description, string? useContext, string? creationTitle) { } + public string? CreationTitle { get { throw null; } } + public string? Description { get { throw null; } } + public string? FriendlyName { get { throw null; } } + public System.Security.Cryptography.CngUIProtectionLevels ProtectionLevel { get { throw null; } } + public string? UseContext { get { throw null; } } + } + [System.FlagsAttribute] + public enum CngUIProtectionLevels + { + None = 0, + ProtectKey = 1, + ForceHighProtection = 2, + } public partial class CryptoConfig { public CryptoConfig() { } @@ -272,6 +576,52 @@ public enum CryptoStreamMode Read = 0, Write = 1, } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public sealed partial class CspKeyContainerInfo + { + public CspKeyContainerInfo(System.Security.Cryptography.CspParameters parameters) { } + public bool Accessible { get { throw null; } } + public bool Exportable { get { throw null; } } + public bool HardwareDevice { get { throw null; } } + public string? KeyContainerName { get { throw null; } } + public System.Security.Cryptography.KeyNumber KeyNumber { get { throw null; } } + public bool MachineKeyStore { get { throw null; } } + public bool Protected { get { throw null; } } + public string? ProviderName { get { throw null; } } + public int ProviderType { get { throw null; } } + public bool RandomlyGenerated { get { throw null; } } + public bool Removable { get { throw null; } } + public string UniqueKeyContainerName { get { throw null; } } + } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public sealed partial class CspParameters + { + public string? KeyContainerName; + public int KeyNumber; + public string? ProviderName; + public int ProviderType; + public CspParameters() { } + public CspParameters(int dwTypeIn) { } + public CspParameters(int dwTypeIn, string? strProviderNameIn) { } + public CspParameters(int dwTypeIn, string? strProviderNameIn, string? strContainerNameIn) { } + public System.Security.Cryptography.CspProviderFlags Flags { get { throw null; } set { } } + [System.CLSCompliantAttribute(false)] + public System.Security.SecureString? KeyPassword { get { throw null; } set { } } + public System.IntPtr ParentWindowHandle { get { throw null; } set { } } + } + [System.FlagsAttribute] + public enum CspProviderFlags + { + NoFlags = 0, + UseMachineKeyStore = 1, + UseDefaultKeyContainer = 2, + UseNonExportableKey = 4, + UseExistingKey = 8, + UseArchivableKey = 16, + UseUserProtectedKey = 32, + NoPrompt = 64, + CreateEphemeralKey = 128, + } public abstract partial class DeriveBytes : System.IDisposable { protected DeriveBytes() { } @@ -292,6 +642,18 @@ protected DES() { } public static bool IsSemiWeakKey(byte[] rgbKey) { throw null; } public static bool IsWeakKey(byte[] rgbKey) { throw null; } } + [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class DESCryptoServiceProvider : System.Security.Cryptography.DES + { + public DESCryptoServiceProvider() { } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + public override void GenerateIV() { } + public override void GenerateKey() { } + } public abstract partial class DSA : System.Security.Cryptography.AsymmetricAlgorithm { protected DSA() { } @@ -361,6 +723,113 @@ public override void ImportFromPem(System.ReadOnlySpan input) { } public bool VerifySignature(System.ReadOnlySpan hash, System.ReadOnlySpan signature, System.Security.Cryptography.DSASignatureFormat signatureFormat) { throw null; } protected virtual bool VerifySignatureCore(System.ReadOnlySpan hash, System.ReadOnlySpan signature, System.Security.Cryptography.DSASignatureFormat signatureFormat) { throw null; } } + public sealed partial class DSACng : System.Security.Cryptography.DSA + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public DSACng() { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public DSACng(int keySize) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public DSACng(System.Security.Cryptography.CngKey key) { } + public System.Security.Cryptography.CngKey Key { get { throw null; } } + public override string? KeyExchangeAlgorithm { get { throw null; } } + public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } + public override string SignatureAlgorithm { get { throw null; } } + public override byte[] CreateSignature(byte[] rgbHash) { throw null; } + protected override void Dispose(bool disposing) { } + public override byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + public override byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + public override System.Security.Cryptography.DSAParameters ExportParameters(bool includePrivateParameters) { throw null; } + protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportParameters(System.Security.Cryptography.DSAParameters parameters) { } + protected override bool TryCreateSignatureCore(System.ReadOnlySpan hash, System.Span destination, System.Security.Cryptography.DSASignatureFormat signatureFormat, out int bytesWritten) { throw null; } + public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + public override bool TryExportPkcs8PrivateKey(System.Span destination, out int bytesWritten) { throw null; } + protected override bool TryHashData(System.ReadOnlySpan source, System.Span destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; } + public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) { throw null; } + protected override bool VerifySignatureCore(System.ReadOnlySpan hash, System.ReadOnlySpan signature, System.Security.Cryptography.DSASignatureFormat signatureFormat) { throw null; } + } + public sealed partial class DSACryptoServiceProvider : System.Security.Cryptography.DSA, System.Security.Cryptography.ICspAsymmetricAlgorithm + { + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + public DSACryptoServiceProvider() { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + public DSACryptoServiceProvider(int dwKeySize) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public DSACryptoServiceProvider(int dwKeySize, System.Security.Cryptography.CspParameters? parameters) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public DSACryptoServiceProvider(System.Security.Cryptography.CspParameters? parameters) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get { throw null; } } + public override string? KeyExchangeAlgorithm { get { throw null; } } + public override int KeySize { get { throw null; } } + public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } + public bool PersistKeyInCsp { get { throw null; } set { } } + public bool PublicOnly { get { throw null; } } + public override string SignatureAlgorithm { get { throw null; } } + public static bool UseMachineKeyStore { get { throw null; } set { } } + public override byte[] CreateSignature(byte[] rgbHash) { throw null; } + protected override void Dispose(bool disposing) { } + public byte[] ExportCspBlob(bool includePrivateParameters) { throw null; } + public override System.Security.Cryptography.DSAParameters ExportParameters(bool includePrivateParameters) { throw null; } + protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + public void ImportCspBlob(byte[] keyBlob) { } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportParameters(System.Security.Cryptography.DSAParameters parameters) { } + public byte[] SignData(byte[] buffer) { throw null; } + public byte[] SignData(byte[] buffer, int offset, int count) { throw null; } + public byte[] SignData(System.IO.Stream inputStream) { throw null; } + public byte[] SignHash(byte[] rgbHash, string? str) { throw null; } + public bool VerifyData(byte[] rgbData, byte[] rgbSignature) { throw null; } + public bool VerifyHash(byte[] rgbHash, string? str, byte[] rgbSignature) { throw null; } + public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) { throw null; } + } + public sealed partial class DSAOpenSsl : System.Security.Cryptography.DSA + { + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public DSAOpenSsl() { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public DSAOpenSsl(int keySize) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public DSAOpenSsl(System.IntPtr handle) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public DSAOpenSsl(System.Security.Cryptography.DSAParameters parameters) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public DSAOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) { } + public override byte[] CreateSignature(byte[] rgbHash) { throw null; } + public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } + public override System.Security.Cryptography.DSAParameters ExportParameters(bool includePrivateParameters) { throw null; } + public override void ImportParameters(System.Security.Cryptography.DSAParameters parameters) { } + public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) { throw null; } + } public partial struct DSAParameters { public int Counter; @@ -493,6 +962,107 @@ protected ECDiffieHellman() { } public override void FromXmlString(string xmlString) { } public override string ToXmlString(bool includePrivateParameters) { throw null; } } + public sealed partial class ECDiffieHellmanCng : System.Security.Cryptography.ECDiffieHellman + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public ECDiffieHellmanCng() { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public ECDiffieHellmanCng(int keySize) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public ECDiffieHellmanCng(System.Security.Cryptography.CngKey key) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public ECDiffieHellmanCng(System.Security.Cryptography.ECCurve curve) { } + public System.Security.Cryptography.CngAlgorithm HashAlgorithm { get { throw null; } set { } } + public byte[]? HmacKey { get { throw null; } set { } } + public System.Security.Cryptography.CngKey Key { get { throw null; } } + public System.Security.Cryptography.ECDiffieHellmanKeyDerivationFunction KeyDerivationFunction { get { throw null; } set { } } + public override int KeySize { get { throw null; } set { } } + public byte[]? Label { get { throw null; } set { } } + public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } + public override System.Security.Cryptography.ECDiffieHellmanPublicKey PublicKey { get { throw null; } } + public byte[]? SecretAppend { get { throw null; } set { } } + public byte[]? SecretPrepend { get { throw null; } set { } } + public byte[]? Seed { get { throw null; } set { } } + public bool UseSecretAgreementAsHmacKey { get { throw null; } } + public override byte[] DeriveKeyFromHash(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[]? secretPrepend, byte[]? secretAppend) { throw null; } + public override byte[] DeriveKeyFromHmac(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[]? hmacKey, byte[]? secretPrepend, byte[]? secretAppend) { throw null; } + public byte[] DeriveKeyMaterial(System.Security.Cryptography.CngKey otherPartyPublicKey) { throw null; } + public override byte[] DeriveKeyMaterial(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey) { throw null; } + public override byte[] DeriveKeyTls(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed) { throw null; } + public Microsoft.Win32.SafeHandles.SafeNCryptSecretHandle DeriveSecretAgreementHandle(System.Security.Cryptography.CngKey otherPartyPublicKey) { throw null; } + public Microsoft.Win32.SafeHandles.SafeNCryptSecretHandle DeriveSecretAgreementHandle(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey) { throw null; } + protected override void Dispose(bool disposing) { } + public override byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + public override byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters) { throw null; } + public override System.Security.Cryptography.ECParameters ExportParameters(bool includePrivateParameters) { throw null; } + public void FromXmlString(string xml, System.Security.Cryptography.ECKeyXmlFormat format) { } + public override void GenerateKey(System.Security.Cryptography.ECCurve curve) { } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportParameters(System.Security.Cryptography.ECParameters parameters) { } + public override void ImportPkcs8PrivateKey(System.ReadOnlySpan source, out int bytesRead) { throw null; } + public string ToXmlString(System.Security.Cryptography.ECKeyXmlFormat format) { throw null; } + public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + public override bool TryExportPkcs8PrivateKey(System.Span destination, out int bytesWritten) { throw null; } + } + public sealed partial class ECDiffieHellmanCngPublicKey : System.Security.Cryptography.ECDiffieHellmanPublicKey + { + internal ECDiffieHellmanCngPublicKey() { } + public System.Security.Cryptography.CngKeyBlobFormat BlobFormat { get { throw null; } } + protected override void Dispose(bool disposing) { } + public override System.Security.Cryptography.ECParameters ExportExplicitParameters() { throw null; } + public override System.Security.Cryptography.ECParameters ExportParameters() { throw null; } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public static System.Security.Cryptography.ECDiffieHellmanPublicKey FromByteArray(byte[] publicKeyBlob, System.Security.Cryptography.CngKeyBlobFormat format) { throw null; } + public static System.Security.Cryptography.ECDiffieHellmanCngPublicKey FromXmlString(string xml) { throw null; } + public System.Security.Cryptography.CngKey Import() { throw null; } + public override string ToXmlString() { throw null; } + } + public enum ECDiffieHellmanKeyDerivationFunction + { + Hash = 0, + Hmac = 1, + Tls = 2, + } + public sealed partial class ECDiffieHellmanOpenSsl : System.Security.Cryptography.ECDiffieHellman + { + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDiffieHellmanOpenSsl() { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDiffieHellmanOpenSsl(int keySize) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDiffieHellmanOpenSsl(System.IntPtr handle) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDiffieHellmanOpenSsl(System.Security.Cryptography.ECCurve curve) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDiffieHellmanOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) { } + public override System.Security.Cryptography.ECDiffieHellmanPublicKey PublicKey { get { throw null; } } + public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } + public override System.Security.Cryptography.ECParameters ExportParameters(bool includePrivateParameters) { throw null; } + public override void ImportParameters(System.Security.Cryptography.ECParameters parameters) { } + } public abstract partial class ECDiffieHellmanPublicKey : System.IDisposable { protected ECDiffieHellmanPublicKey() { } @@ -558,6 +1128,91 @@ public override void FromXmlString(string xmlString) { } public bool VerifyHash(System.ReadOnlySpan hash, System.ReadOnlySpan signature, System.Security.Cryptography.DSASignatureFormat signatureFormat) { throw null; } protected virtual bool VerifyHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan signature, System.Security.Cryptography.DSASignatureFormat signatureFormat) { throw null; } } + public sealed partial class ECDsaCng : System.Security.Cryptography.ECDsa + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public ECDsaCng() { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public ECDsaCng(int keySize) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public ECDsaCng(System.Security.Cryptography.CngKey key) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public ECDsaCng(System.Security.Cryptography.ECCurve curve) { } + public System.Security.Cryptography.CngAlgorithm HashAlgorithm { get { throw null; } set { } } + public System.Security.Cryptography.CngKey Key { get { throw null; } } + public override int KeySize { get { throw null; } set { } } + public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } + protected override void Dispose(bool disposing) { } + public override byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + public override byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + public override System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters) { throw null; } + public override System.Security.Cryptography.ECParameters ExportParameters(bool includePrivateParameters) { throw null; } + public void FromXmlString(string xml, System.Security.Cryptography.ECKeyXmlFormat format) { } + public override void GenerateKey(System.Security.Cryptography.ECCurve curve) { } + protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportParameters(System.Security.Cryptography.ECParameters parameters) { } + public override void ImportPkcs8PrivateKey(System.ReadOnlySpan source, out int bytesRead) { throw null; } + public byte[] SignData(byte[] data) { throw null; } + public byte[] SignData(byte[] data, int offset, int count) { throw null; } + public byte[] SignData(System.IO.Stream data) { throw null; } + public override byte[] SignHash(byte[] hash) { throw null; } + public string ToXmlString(System.Security.Cryptography.ECKeyXmlFormat format) { throw null; } + public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + public override bool TryExportPkcs8PrivateKey(System.Span destination, out int bytesWritten) { throw null; } + protected override bool TryHashData(System.ReadOnlySpan source, System.Span destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; } + public override bool TrySignHash(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } + protected override bool TrySignHashCore(System.ReadOnlySpan hash, System.Span destination, System.Security.Cryptography.DSASignatureFormat signatureFormat, out int bytesWritten) { throw null; } + public bool VerifyData(byte[] data, byte[] signature) { throw null; } + public bool VerifyData(byte[] data, int offset, int count, byte[] signature) { throw null; } + public bool VerifyData(System.IO.Stream data, byte[] signature) { throw null; } + public override bool VerifyHash(byte[] hash, byte[] signature) { throw null; } + public override bool VerifyHash(System.ReadOnlySpan hash, System.ReadOnlySpan signature) { throw null; } + protected override bool VerifyHashCore(System.ReadOnlySpan hash, System.ReadOnlySpan signature, System.Security.Cryptography.DSASignatureFormat signatureFormat) { throw null; } + } + public sealed partial class ECDsaOpenSsl : System.Security.Cryptography.ECDsa + { + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDsaOpenSsl() { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDsaOpenSsl(int keySize) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDsaOpenSsl(System.IntPtr handle) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDsaOpenSsl(System.Security.Cryptography.ECCurve curve) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public ECDsaOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) { } + public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } + public override byte[] SignHash(byte[] hash) { throw null; } + public override bool VerifyHash(byte[] hash, byte[] signature) { throw null; } + } + public enum ECKeyXmlFormat + { + Rfc4050 = 0, + } public partial struct ECParameters { public System.Security.Cryptography.ECCurve Curve; @@ -810,6 +1465,12 @@ public partial interface ICryptoTransform : System.IDisposable int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset); byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount); } + public partial interface ICspAsymmetricAlgorithm + { + System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get; } + byte[] ExportCspBlob(bool includePrivateParameters); + void ImportCspBlob(byte[] rawData); + } public sealed partial class IncrementalHash : System.IDisposable { internal IncrementalHash() { } @@ -842,6 +1503,11 @@ protected KeyedHashAlgorithm() { } public static new System.Security.Cryptography.KeyedHashAlgorithm? Create(string algName) { throw null; } protected override void Dispose(bool disposing) { } } + public enum KeyNumber + { + Exchange = 1, + Signature = 2, + } public sealed partial class KeySizes { public KeySizes(int minSize, int maxSize, int skipSize) { } @@ -872,6 +1538,18 @@ protected MD5() { } public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static bool TryHashData(System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } } + [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class MD5CryptoServiceProvider : System.Security.Cryptography.MD5 + { + public MD5CryptoServiceProvider() { } + protected override void Dispose(bool disposing) { } + protected override void HashCore(byte[] array, int ibStart, int cbSize) { } + protected override void HashCore(System.ReadOnlySpan source) { } + protected override byte[] HashFinal() { throw null; } + public override void Initialize() { } + protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } + } public sealed partial class Oid { public Oid() { } @@ -927,6 +1605,30 @@ public enum PaddingMode ANSIX923 = 4, ISO10126 = 5, } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public partial class PasswordDeriveBytes : System.Security.Cryptography.DeriveBytes + { + public PasswordDeriveBytes(byte[] password, byte[]? salt) { } + public PasswordDeriveBytes(byte[] password, byte[]? salt, System.Security.Cryptography.CspParameters? cspParams) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] + public PasswordDeriveBytes(byte[] password, byte[]? salt, string hashName, int iterations) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] + public PasswordDeriveBytes(byte[] password, byte[]? salt, string hashName, int iterations, System.Security.Cryptography.CspParameters? cspParams) { } + public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt) { } + public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt, System.Security.Cryptography.CspParameters? cspParams) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] + public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt, string strHashName, int iterations) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] + public PasswordDeriveBytes(string strPassword, byte[]? rgbSalt, string strHashName, int iterations, System.Security.Cryptography.CspParameters? cspParams) { } + public string HashName { get { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The hash implementation might be removed. Ensure the referenced hash algorithm is not trimmed.")] set { } } + public int IterationCount { get { throw null; } set { } } + public byte[]? Salt { get { throw null; } set { } } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public byte[] CryptDeriveKey(string? algname, string? alghashname, int keySize, byte[] rgbIV) { throw null; } + protected override void Dispose(bool disposing) { } + public override byte[] GetBytes(int cb) { throw null; } + public override void Reset() { } + } public enum PbeEncryptionAlgorithm { Unknown = 0, @@ -996,6 +1698,20 @@ protected RC2() { } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The default algorithm implementations might be removed, use strong type references like 'RSA.Create()' instead.")] public static new System.Security.Cryptography.RC2? Create(string AlgName) { throw null; } } + [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class RC2CryptoServiceProvider : System.Security.Cryptography.RC2 + { + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public RC2CryptoServiceProvider() { } + public override int EffectiveKeySize { get { throw null; } set { } } + public bool UseSalt { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + public override void GenerateIV() { } + public override void GenerateKey() { } + } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public partial class Rfc2898DeriveBytes : System.Security.Cryptography.DeriveBytes { @@ -1054,6 +1770,21 @@ protected override void Dispose(bool disposing) { } public override void GenerateIV() { } public override void GenerateKey() { } } + [System.ObsoleteAttribute("RNGCryptoServiceProvider is obsolete. To generate a random number, use one of the RandomNumberGenerator static methods instead.", DiagnosticId = "SYSLIB0023", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class RNGCryptoServiceProvider : System.Security.Cryptography.RandomNumberGenerator + { + public RNGCryptoServiceProvider() { } + public RNGCryptoServiceProvider(byte[] rgb) { } + public RNGCryptoServiceProvider(System.Security.Cryptography.CspParameters? cspParams) { } + public RNGCryptoServiceProvider(string str) { } + protected override void Dispose(bool disposing) { } + public override void GetBytes(byte[] data) { } + public override void GetBytes(byte[] data, int offset, int count) { } + public override void GetBytes(System.Span data) { } + public override void GetNonZeroBytes(byte[] data) { } + public override void GetNonZeroBytes(System.Span data) { } + } public abstract partial class RSA : System.Security.Cryptography.AsymmetricAlgorithm { protected RSA() { } @@ -1114,6 +1845,82 @@ public override void ImportFromPem(System.ReadOnlySpan input) { } public virtual bool VerifyHash(byte[] hash, byte[] signature, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } public virtual bool VerifyHash(System.ReadOnlySpan hash, System.ReadOnlySpan signature, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } } + public sealed partial class RSACng : System.Security.Cryptography.RSA + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public RSACng() { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public RSACng(int keySize) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public RSACng(System.Security.Cryptography.CngKey key) { } + public System.Security.Cryptography.CngKey Key { get { throw null; } } + public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } + public override byte[] Decrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } + protected override void Dispose(bool disposing) { } + public override byte[] Encrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } + public override byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + public override byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; } + public override System.Security.Cryptography.RSAParameters ExportParameters(bool includePrivateParameters) { throw null; } + protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportParameters(System.Security.Cryptography.RSAParameters parameters) { } + public override void ImportPkcs8PrivateKey(System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override byte[] SignHash(byte[] hash, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } + public override bool TryDecrypt(System.ReadOnlySpan data, System.Span destination, System.Security.Cryptography.RSAEncryptionPadding padding, out int bytesWritten) { throw null; } + public override bool TryEncrypt(System.ReadOnlySpan data, System.Span destination, System.Security.Cryptography.RSAEncryptionPadding padding, out int bytesWritten) { throw null; } + public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span destination, out int bytesWritten) { throw null; } + public override bool TryExportPkcs8PrivateKey(System.Span destination, out int bytesWritten) { throw null; } + protected override bool TryHashData(System.ReadOnlySpan data, System.Span destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; } + public override bool TrySignHash(System.ReadOnlySpan hash, System.Span destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding, out int bytesWritten) { throw null; } + public override bool VerifyHash(byte[] hash, byte[] signature, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } + public override bool VerifyHash(System.ReadOnlySpan hash, System.ReadOnlySpan signature, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } + } + public sealed partial class RSACryptoServiceProvider : System.Security.Cryptography.RSA, System.Security.Cryptography.ICspAsymmetricAlgorithm + { + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public RSACryptoServiceProvider() { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public RSACryptoServiceProvider(int dwKeySize) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public RSACryptoServiceProvider(int dwKeySize, System.Security.Cryptography.CspParameters? parameters) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public RSACryptoServiceProvider(System.Security.Cryptography.CspParameters? parameters) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public System.Security.Cryptography.CspKeyContainerInfo CspKeyContainerInfo { get { throw null; } } + public override string? KeyExchangeAlgorithm { get { throw null; } } + public override int KeySize { get { throw null; } } + public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } + public bool PersistKeyInCsp { get { throw null; } set { } } + public bool PublicOnly { get { throw null; } } + public override string SignatureAlgorithm { get { throw null; } } + public static bool UseMachineKeyStore { get { throw null; } set { } } + public byte[] Decrypt(byte[] rgb, bool fOAEP) { throw null; } + public override byte[] Decrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } + public override byte[] DecryptValue(byte[] rgb) { throw null; } + protected override void Dispose(bool disposing) { } + public byte[] Encrypt(byte[] rgb, bool fOAEP) { throw null; } + public override byte[] Encrypt(byte[] data, System.Security.Cryptography.RSAEncryptionPadding padding) { throw null; } + public override byte[] EncryptValue(byte[] rgb) { throw null; } + public byte[] ExportCspBlob(bool includePrivateParameters) { throw null; } + public override System.Security.Cryptography.RSAParameters ExportParameters(bool includePrivateParameters) { throw null; } + protected override byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + protected override byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + public void ImportCspBlob(byte[] keyBlob) { } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan passwordBytes, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan password, System.ReadOnlySpan source, out int bytesRead) { throw null; } + public override void ImportParameters(System.Security.Cryptography.RSAParameters parameters) { } + public byte[] SignData(byte[] buffer, int offset, int count, object halg) { throw null; } + public byte[] SignData(byte[] buffer, object halg) { throw null; } + public byte[] SignData(System.IO.Stream inputStream, object halg) { throw null; } + public override byte[] SignHash(byte[] hash, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } + public byte[] SignHash(byte[] rgbHash, string? str) { throw null; } + public bool VerifyData(byte[] buffer, object halg, byte[] signature) { throw null; } + public override bool VerifyHash(byte[] hash, byte[] signature, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; } + public bool VerifyHash(byte[] rgbHash, string str, byte[] rgbSignature) { throw null; } + } public sealed partial class RSAEncryptionPadding : System.IEquatable { internal RSAEncryptionPadding() { } @@ -1156,6 +1963,42 @@ public RSAOAEPKeyExchangeFormatter(System.Security.Cryptography.AsymmetricAlgori public override byte[] CreateKeyExchange(byte[] rgbData, System.Type? symAlgType) { throw null; } public override void SetKey(System.Security.Cryptography.AsymmetricAlgorithm key) { } } + public sealed partial class RSAOpenSsl : System.Security.Cryptography.RSA + { + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public RSAOpenSsl() { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public RSAOpenSsl(int keySize) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public RSAOpenSsl(System.IntPtr handle) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public RSAOpenSsl(System.Security.Cryptography.RSAParameters parameters) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public RSAOpenSsl(System.Security.Cryptography.SafeEvpPKeyHandle pkeyHandle) { } + public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateKeyHandle() { throw null; } + public override System.Security.Cryptography.RSAParameters ExportParameters(bool includePrivateParameters) { throw null; } + public override void ImportParameters(System.Security.Cryptography.RSAParameters parameters) { } + } public partial struct RSAParameters { public byte[]? D; @@ -1222,6 +2065,30 @@ public enum RSASignaturePaddingMode Pkcs1 = 0, Pss = 1, } + public sealed partial class SafeEvpPKeyHandle : System.Runtime.InteropServices.SafeHandle + { + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public SafeEvpPKeyHandle() : base (default(System.IntPtr), default(bool)) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public SafeEvpPKeyHandle(System.IntPtr handle, bool ownsHandle) : base (default(System.IntPtr), default(bool)) { } + public override bool IsInvalid { get { throw null; } } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("android")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")] + public static long OpenSslVersion { get { throw null; } } + public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateHandle() { throw null; } + protected override bool ReleaseHandle() { throw null; } + } public abstract partial class SHA1 : System.Security.Cryptography.HashAlgorithm { public const int HashSizeInBits = 160; @@ -1241,6 +2108,18 @@ protected SHA1() { } } [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class SHA1CryptoServiceProvider : System.Security.Cryptography.SHA1 + { + public SHA1CryptoServiceProvider() { } + protected override void Dispose(bool disposing) { } + protected override void HashCore(byte[] array, int ibStart, int cbSize) { } + protected override void HashCore(System.ReadOnlySpan source) { } + protected override byte[] HashFinal() { throw null; } + public override void Initialize() { } + protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } + } + [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public sealed partial class SHA1Managed : System.Security.Cryptography.SHA1 { public SHA1Managed() { } @@ -1270,6 +2149,18 @@ protected SHA256() { } } [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class SHA256CryptoServiceProvider : System.Security.Cryptography.SHA256 + { + public SHA256CryptoServiceProvider() { } + protected override void Dispose(bool disposing) { } + protected override void HashCore(byte[] array, int ibStart, int cbSize) { } + protected override void HashCore(System.ReadOnlySpan source) { } + protected override byte[] HashFinal() { throw null; } + public override void Initialize() { } + protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } + } + [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public sealed partial class SHA256Managed : System.Security.Cryptography.SHA256 { public SHA256Managed() { } @@ -1299,6 +2190,18 @@ protected SHA384() { } } [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class SHA384CryptoServiceProvider : System.Security.Cryptography.SHA384 + { + public SHA384CryptoServiceProvider() { } + protected override void Dispose(bool disposing) { } + protected override void HashCore(byte[] array, int ibStart, int cbSize) { } + protected override void HashCore(System.ReadOnlySpan source) { } + protected override byte[] HashFinal() { throw null; } + public override void Initialize() { } + protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } + } + [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public sealed partial class SHA384Managed : System.Security.Cryptography.SHA384 { public SHA384Managed() { } @@ -1328,6 +2231,18 @@ protected SHA512() { } } [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class SHA512CryptoServiceProvider : System.Security.Cryptography.SHA512 + { + public SHA512CryptoServiceProvider() { } + protected override void Dispose(bool disposing) { } + protected override void HashCore(byte[] array, int ibStart, int cbSize) { } + protected override void HashCore(System.ReadOnlySpan source) { } + protected override byte[] HashFinal() { throw null; } + public override void Initialize() { } + protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } + } + [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public sealed partial class SHA512Managed : System.Security.Cryptography.SHA512 { public SHA512Managed() { } @@ -1448,4 +2363,766 @@ protected TripleDES() { } public static new System.Security.Cryptography.TripleDES? Create(string str) { throw null; } public static bool IsWeakKey(byte[] rgbKey) { throw null; } } + public sealed partial class TripleDESCng : System.Security.Cryptography.TripleDES + { + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public TripleDESCng() { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public TripleDESCng(string keyName) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public TripleDESCng(string keyName, System.Security.Cryptography.CngProvider provider) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public TripleDESCng(string keyName, System.Security.Cryptography.CngProvider provider, System.Security.Cryptography.CngKeyOpenOptions openOptions) { } + public override byte[] Key { get { throw null; } set { } } + public override int KeySize { get { throw null; } set { } } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + protected override void Dispose(bool disposing) { } + public override void GenerateIV() { } + public override void GenerateKey() { } + protected override bool TryDecryptCbcCore(System.ReadOnlySpan ciphertext, System.ReadOnlySpan iv, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, out int bytesWritten) { throw null; } + protected override bool TryDecryptCfbCore(System.ReadOnlySpan ciphertext, System.ReadOnlySpan iv, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, int feedbackSizeInBits, out int bytesWritten) { throw null; } + protected override bool TryDecryptEcbCore(System.ReadOnlySpan ciphertext, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, out int bytesWritten) { throw null; } + protected override bool TryEncryptCbcCore(System.ReadOnlySpan plaintext, System.ReadOnlySpan iv, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, out int bytesWritten) { throw null; } + protected override bool TryEncryptCfbCore(System.ReadOnlySpan plaintext, System.ReadOnlySpan iv, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, int feedbackSizeInBits, out int bytesWritten) { throw null; } + protected override bool TryEncryptEcbCore(System.ReadOnlySpan plaintext, System.Span destination, System.Security.Cryptography.PaddingMode paddingMode, out int bytesWritten) { throw null; } + } + [System.ObsoleteAttribute("Derived cryptographic types are obsolete. Use the Create method on the base type instead.", DiagnosticId = "SYSLIB0021", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed partial class TripleDESCryptoServiceProvider : System.Security.Cryptography.TripleDES + { + public TripleDESCryptoServiceProvider() { } + public override int BlockSize { get { throw null; } set { } } + public override int FeedbackSize { get { throw null; } set { } } + public override byte[] IV { get { throw null; } set { } } + public override byte[] Key { get { throw null; } set { } } + public override int KeySize { get { throw null; } set { } } + public override System.Security.Cryptography.KeySizes[] LegalBlockSizes { get { throw null; } } + public override System.Security.Cryptography.KeySizes[] LegalKeySizes { get { throw null; } } + public override System.Security.Cryptography.CipherMode Mode { get { throw null; } set { } } + public override System.Security.Cryptography.PaddingMode Padding { get { throw null; } set { } } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor() { throw null; } + public override System.Security.Cryptography.ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) { throw null; } + protected override void Dispose(bool disposing) { } + public override void GenerateIV() { } + public override void GenerateKey() { } + } +} +namespace System.Security.Cryptography.X509Certificates +{ + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public sealed partial class CertificateRequest + { + public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.ECDsa key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { } + public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.RSA key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { } + public CertificateRequest(System.Security.Cryptography.X509Certificates.X500DistinguishedName subjectName, System.Security.Cryptography.X509Certificates.PublicKey publicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { } + public CertificateRequest(string subjectName, System.Security.Cryptography.ECDsa key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { } + public CertificateRequest(string subjectName, System.Security.Cryptography.RSA key, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { } + public System.Collections.ObjectModel.Collection CertificateExtensions { get { throw null; } } + public System.Security.Cryptography.HashAlgorithmName HashAlgorithm { get { throw null; } } + public System.Security.Cryptography.X509Certificates.PublicKey PublicKey { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X500DistinguishedName SubjectName { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509Certificate2 Create(System.Security.Cryptography.X509Certificates.X500DistinguishedName issuerName, System.Security.Cryptography.X509Certificates.X509SignatureGenerator generator, System.DateTimeOffset notBefore, System.DateTimeOffset notAfter, byte[] serialNumber) { throw null; } + public System.Security.Cryptography.X509Certificates.X509Certificate2 Create(System.Security.Cryptography.X509Certificates.X500DistinguishedName issuerName, System.Security.Cryptography.X509Certificates.X509SignatureGenerator generator, System.DateTimeOffset notBefore, System.DateTimeOffset notAfter, System.ReadOnlySpan serialNumber) { throw null; } + public System.Security.Cryptography.X509Certificates.X509Certificate2 Create(System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCertificate, System.DateTimeOffset notBefore, System.DateTimeOffset notAfter, byte[] serialNumber) { throw null; } + public System.Security.Cryptography.X509Certificates.X509Certificate2 Create(System.Security.Cryptography.X509Certificates.X509Certificate2 issuerCertificate, System.DateTimeOffset notBefore, System.DateTimeOffset notAfter, System.ReadOnlySpan serialNumber) { throw null; } + public System.Security.Cryptography.X509Certificates.X509Certificate2 CreateSelfSigned(System.DateTimeOffset notBefore, System.DateTimeOffset notAfter) { throw null; } + public byte[] CreateSigningRequest() { throw null; } + public byte[] CreateSigningRequest(System.Security.Cryptography.X509Certificates.X509SignatureGenerator signatureGenerator) { throw null; } + } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + public static partial class DSACertificateExtensions + { + public static System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate, System.Security.Cryptography.DSA privateKey) { throw null; } + public static System.Security.Cryptography.DSA? GetDSAPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } + public static System.Security.Cryptography.DSA? GetDSAPublicKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } + } + public static partial class ECDsaCertificateExtensions + { + public static System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate, System.Security.Cryptography.ECDsa privateKey) { throw null; } + public static System.Security.Cryptography.ECDsa? GetECDsaPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } + public static System.Security.Cryptography.ECDsa? GetECDsaPublicKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } + } + [System.FlagsAttribute] + public enum OpenFlags + { + ReadOnly = 0, + ReadWrite = 1, + MaxAllowed = 2, + OpenExistingOnly = 4, + IncludeArchived = 8, + } + public sealed partial class PublicKey + { + public PublicKey(System.Security.Cryptography.AsymmetricAlgorithm key) { } + public PublicKey(System.Security.Cryptography.Oid oid, System.Security.Cryptography.AsnEncodedData parameters, System.Security.Cryptography.AsnEncodedData keyValue) { } + public System.Security.Cryptography.AsnEncodedData EncodedKeyValue { get { throw null; } } + public System.Security.Cryptography.AsnEncodedData EncodedParameters { get { throw null; } } + [System.ObsoleteAttribute("PublicKey.Key is obsolete. Use the appropriate method to get the public key, such as GetRSAPublicKey.", DiagnosticId = "SYSLIB0027", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public System.Security.Cryptography.AsymmetricAlgorithm Key { get { throw null; } } + public System.Security.Cryptography.Oid Oid { get { throw null; } } + public static System.Security.Cryptography.X509Certificates.PublicKey CreateFromSubjectPublicKeyInfo(System.ReadOnlySpan source, out int bytesRead) { throw null; } + public byte[] ExportSubjectPublicKeyInfo() { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + public System.Security.Cryptography.DSA? GetDSAPublicKey() { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public System.Security.Cryptography.ECDiffieHellman? GetECDiffieHellmanPublicKey() { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public System.Security.Cryptography.ECDsa? GetECDsaPublicKey() { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public System.Security.Cryptography.RSA? GetRSAPublicKey() { throw null; } + public bool TryExportSubjectPublicKeyInfo(System.Span destination, out int bytesWritten) { throw null; } + } + public static partial class RSACertificateExtensions + { + public static System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate, System.Security.Cryptography.RSA privateKey) { throw null; } + public static System.Security.Cryptography.RSA? GetRSAPrivateKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } + public static System.Security.Cryptography.RSA? GetRSAPublicKey(this System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } + } + public enum StoreLocation + { + CurrentUser = 1, + LocalMachine = 2, + } + public enum StoreName + { + AddressBook = 1, + AuthRoot = 2, + CertificateAuthority = 3, + Disallowed = 4, + My = 5, + Root = 6, + TrustedPeople = 7, + TrustedPublisher = 8, + } + public sealed partial class SubjectAlternativeNameBuilder + { + public SubjectAlternativeNameBuilder() { } + public void AddDnsName(string dnsName) { } + public void AddEmailAddress(string emailAddress) { } + public void AddIpAddress(System.Net.IPAddress ipAddress) { } + public void AddUri(System.Uri uri) { } + public void AddUserPrincipalName(string upn) { } + public System.Security.Cryptography.X509Certificates.X509Extension Build(bool critical = false) { throw null; } + } + public sealed partial class X500DistinguishedName : System.Security.Cryptography.AsnEncodedData + { + public X500DistinguishedName(byte[] encodedDistinguishedName) { } + public X500DistinguishedName(System.ReadOnlySpan encodedDistinguishedName) { } + public X500DistinguishedName(System.Security.Cryptography.AsnEncodedData encodedDistinguishedName) { } + public X500DistinguishedName(System.Security.Cryptography.X509Certificates.X500DistinguishedName distinguishedName) { } + public X500DistinguishedName(string distinguishedName) { } + public X500DistinguishedName(string distinguishedName, System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags flag) { } + public string Name { get { throw null; } } + public string Decode(System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags flag) { throw null; } + public override string Format(bool multiLine) { throw null; } + } + [System.FlagsAttribute] + public enum X500DistinguishedNameFlags + { + None = 0, + Reversed = 1, + UseSemicolons = 16, + DoNotUsePlusSign = 32, + DoNotUseQuotes = 64, + UseCommas = 128, + UseNewLines = 256, + UseUTF8Encoding = 4096, + UseT61Encoding = 8192, + ForceUTF8Encoding = 16384, + } + public sealed partial class X509BasicConstraintsExtension : System.Security.Cryptography.X509Certificates.X509Extension + { + public X509BasicConstraintsExtension() { } + public X509BasicConstraintsExtension(bool certificateAuthority, bool hasPathLengthConstraint, int pathLengthConstraint, bool critical) { } + public X509BasicConstraintsExtension(System.Security.Cryptography.AsnEncodedData encodedBasicConstraints, bool critical) { } + public bool CertificateAuthority { get { throw null; } } + public bool HasPathLengthConstraint { get { throw null; } } + public int PathLengthConstraint { get { throw null; } } + public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } + } + public partial class X509Certificate : System.IDisposable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable + { + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate() { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(byte[] data) { } + [System.CLSCompliantAttribute(false)] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(byte[] rawData, System.Security.SecureString? password) { } + [System.CLSCompliantAttribute(false)] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(byte[] rawData, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(byte[] rawData, string? password) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(System.IntPtr handle) { } + public X509Certificate(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(System.Security.Cryptography.X509Certificates.X509Certificate cert) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(string fileName) { } + [System.CLSCompliantAttribute(false)] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(string fileName, System.Security.SecureString? password) { } + [System.CLSCompliantAttribute(false)] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(string fileName, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(string fileName, string? password) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + public System.IntPtr Handle { get { throw null; } } + public string Issuer { get { throw null; } } + public string Subject { get { throw null; } } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509Certificate CreateFromCertFile(string filename) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509Certificate CreateFromSignedFile(string filename) { throw null; } + public void Dispose() { } + protected virtual void Dispose(bool disposing) { } + public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } + public virtual bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Security.Cryptography.X509Certificates.X509Certificate? other) { throw null; } + public virtual byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType) { throw null; } + [System.CLSCompliantAttribute(false)] + public virtual byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, System.Security.SecureString? password) { throw null; } + public virtual byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, string? password) { throw null; } + protected static string FormatDate(System.DateTime date) { throw null; } + public virtual byte[] GetCertHash() { throw null; } + public virtual byte[] GetCertHash(System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + public virtual string GetCertHashString() { throw null; } + public virtual string GetCertHashString(System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } + public virtual string GetEffectiveDateString() { throw null; } + public virtual string GetExpirationDateString() { throw null; } + public virtual string GetFormat() { throw null; } + public override int GetHashCode() { throw null; } + [System.ObsoleteAttribute("X509Certificate.GetIssuerName has been deprecated. Use the Issuer property instead.")] + public virtual string GetIssuerName() { throw null; } + public virtual string GetKeyAlgorithm() { throw null; } + public virtual byte[] GetKeyAlgorithmParameters() { throw null; } + public virtual string GetKeyAlgorithmParametersString() { throw null; } + [System.ObsoleteAttribute("X509Certificate.GetName has been deprecated. Use the Subject property instead.")] + public virtual string GetName() { throw null; } + public virtual byte[] GetPublicKey() { throw null; } + public virtual string GetPublicKeyString() { throw null; } + public virtual byte[] GetRawCertData() { throw null; } + public virtual string GetRawCertDataString() { throw null; } + public virtual byte[] GetSerialNumber() { throw null; } + public virtual string GetSerialNumberString() { throw null; } + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public virtual void Import(byte[] rawData) { } + [System.CLSCompliantAttribute(false)] + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public virtual void Import(byte[] rawData, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public virtual void Import(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public virtual void Import(string fileName) { } + [System.CLSCompliantAttribute(false)] + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public virtual void Import(string fileName, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public virtual void Import(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + public virtual void Reset() { } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } + void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } + public override string ToString() { throw null; } + public virtual string ToString(bool fVerbose) { throw null; } + public virtual bool TryGetCertHash(System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Span destination, out int bytesWritten) { throw null; } + } + public partial class X509Certificate2 : System.Security.Cryptography.X509Certificates.X509Certificate + { + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2() { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(byte[] rawData) { } + [System.CLSCompliantAttribute(false)] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(byte[] rawData, System.Security.SecureString? password) { } + [System.CLSCompliantAttribute(false)] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(byte[] rawData, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(byte[] rawData, string? password) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(System.IntPtr handle) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(System.ReadOnlySpan rawData) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(System.ReadOnlySpan rawData, System.ReadOnlySpan password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } + protected X509Certificate2(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(System.Security.Cryptography.X509Certificates.X509Certificate certificate) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(string fileName) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(string fileName, System.ReadOnlySpan password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } + [System.CLSCompliantAttribute(false)] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(string fileName, System.Security.SecureString? password) { } + [System.CLSCompliantAttribute(false)] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(string fileName, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(string fileName, string? password) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public X509Certificate2(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + public bool Archived { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public System.Security.Cryptography.X509Certificates.X509ExtensionCollection Extensions { get { throw null; } } + public string FriendlyName { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } } + public bool HasPrivateKey { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X500DistinguishedName IssuerName { get { throw null; } } + public System.DateTime NotAfter { get { throw null; } } + public System.DateTime NotBefore { get { throw null; } } + [System.ObsoleteAttribute("X509Certificate2.PrivateKey is obsolete. Use the appropriate method to get the private key, such as GetRSAPrivateKey, or use the CopyWithPrivateKey method to create a new instance with a private key.", DiagnosticId = "SYSLIB0028", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public System.Security.Cryptography.AsymmetricAlgorithm? PrivateKey { get { throw null; } set { } } + public System.Security.Cryptography.X509Certificates.PublicKey PublicKey { get { throw null; } } + public byte[] RawData { get { throw null; } } + public System.ReadOnlyMemory RawDataMemory { get { throw null; } } + public string SerialNumber { get { throw null; } } + public System.Security.Cryptography.Oid SignatureAlgorithm { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X500DistinguishedName SubjectName { get { throw null; } } + public string Thumbprint { get { throw null; } } + public int Version { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509Certificate2 CopyWithPrivateKey(System.Security.Cryptography.ECDiffieHellman privateKey) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromEncryptedPem(System.ReadOnlySpan certPem, System.ReadOnlySpan keyPem, System.ReadOnlySpan password) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromEncryptedPemFile(string certPemFilePath, System.ReadOnlySpan password, string? keyPemFilePath = null) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromPem(System.ReadOnlySpan certPem) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromPem(System.ReadOnlySpan certPem, System.ReadOnlySpan keyPem) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateFromPemFile(string certPemFilePath, string? keyPemFilePath = null) { throw null; } + public string ExportCertificatePem() { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509ContentType GetCertContentType(byte[] rawData) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509ContentType GetCertContentType(System.ReadOnlySpan rawData) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static System.Security.Cryptography.X509Certificates.X509ContentType GetCertContentType(string fileName) { throw null; } + public System.Security.Cryptography.ECDiffieHellman? GetECDiffieHellmanPrivateKey() { throw null; } + public System.Security.Cryptography.ECDiffieHellman? GetECDiffieHellmanPublicKey() { throw null; } + public string GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType nameType, bool forIssuer) { throw null; } + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public override void Import(byte[] rawData) { } + [System.CLSCompliantAttribute(false)] + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public override void Import(byte[] rawData, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public override void Import(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public override void Import(string fileName) { } + [System.CLSCompliantAttribute(false)] + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public override void Import(string fileName, System.Security.SecureString? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + [System.ObsoleteAttribute("X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.", DiagnosticId = "SYSLIB0026", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] + public override void Import(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) { } + public override void Reset() { } + public override string ToString() { throw null; } + public override string ToString(bool verbose) { throw null; } + public bool TryExportCertificatePem(System.Span destination, out int charsWritten) { throw null; } + public bool Verify() { throw null; } + } + public partial class X509Certificate2Collection : System.Security.Cryptography.X509Certificates.X509CertificateCollection, System.Collections.Generic.IEnumerable, System.Collections.IEnumerable + { + public X509Certificate2Collection() { } + public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } + public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } + public X509Certificate2Collection(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { } + public new System.Security.Cryptography.X509Certificates.X509Certificate2 this[int index] { get { throw null; } set { } } + public int Add(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } + public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } + public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { } + public bool Contains(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } + public byte[]? Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType) { throw null; } + public byte[]? Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, string? password) { throw null; } + public string ExportCertificatePems() { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + public string ExportPkcs7Pem() { throw null; } + public System.Security.Cryptography.X509Certificates.X509Certificate2Collection Find(System.Security.Cryptography.X509Certificates.X509FindType findType, object findValue, bool validOnly) { throw null; } + public new System.Security.Cryptography.X509Certificates.X509Certificate2Enumerator GetEnumerator() { throw null; } + public void Import(byte[] rawData) { } + public void Import(byte[] rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } + public void Import(System.ReadOnlySpan rawData) { } + public void Import(System.ReadOnlySpan rawData, System.ReadOnlySpan password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } + public void Import(System.ReadOnlySpan rawData, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } + public void Import(string fileName) { } + public void Import(string fileName, System.ReadOnlySpan password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } + public void Import(string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.DefaultKeySet) { } + public void ImportFromPem(System.ReadOnlySpan certPem) { } + public void ImportFromPemFile(string certPemFilePath) { } + public void Insert(int index, System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } + public void Remove(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } + public void RemoveRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } + public void RemoveRange(System.Security.Cryptography.X509Certificates.X509Certificate2[] certificates) { } + System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } + public bool TryExportCertificatePems(System.Span destination, out int charsWritten) { throw null; } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("ios")] + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("tvos")] + public bool TryExportPkcs7Pem(System.Span destination, out int charsWritten) { throw null; } + } + public sealed partial class X509Certificate2Enumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable + { + internal X509Certificate2Enumerator() { } + public System.Security.Cryptography.X509Certificates.X509Certificate2 Current { get { throw null; } } + object System.Collections.IEnumerator.Current { get { throw null; } } + public bool MoveNext() { throw null; } + public void Reset() { } + bool System.Collections.IEnumerator.MoveNext() { throw null; } + void System.Collections.IEnumerator.Reset() { } + void System.IDisposable.Dispose() { } + } + public partial class X509CertificateCollection : System.Collections.CollectionBase + { + public X509CertificateCollection() { } + public X509CertificateCollection(System.Security.Cryptography.X509Certificates.X509CertificateCollection value) { } + public X509CertificateCollection(System.Security.Cryptography.X509Certificates.X509Certificate[] value) { } + public System.Security.Cryptography.X509Certificates.X509Certificate this[int index] { get { throw null; } set { } } + public int Add(System.Security.Cryptography.X509Certificates.X509Certificate value) { throw null; } + public void AddRange(System.Security.Cryptography.X509Certificates.X509CertificateCollection value) { } + public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate[] value) { } + public bool Contains(System.Security.Cryptography.X509Certificates.X509Certificate value) { throw null; } + public void CopyTo(System.Security.Cryptography.X509Certificates.X509Certificate[] array, int index) { } + public new System.Security.Cryptography.X509Certificates.X509CertificateCollection.X509CertificateEnumerator GetEnumerator() { throw null; } + public override int GetHashCode() { throw null; } + public int IndexOf(System.Security.Cryptography.X509Certificates.X509Certificate value) { throw null; } + public void Insert(int index, System.Security.Cryptography.X509Certificates.X509Certificate value) { } + protected override void OnValidate(object value) { } + public void Remove(System.Security.Cryptography.X509Certificates.X509Certificate value) { } + public partial class X509CertificateEnumerator : System.Collections.IEnumerator + { + public X509CertificateEnumerator(System.Security.Cryptography.X509Certificates.X509CertificateCollection mappings) { } + public System.Security.Cryptography.X509Certificates.X509Certificate Current { get { throw null; } } + object System.Collections.IEnumerator.Current { get { throw null; } } + public bool MoveNext() { throw null; } + public void Reset() { } + bool System.Collections.IEnumerator.MoveNext() { throw null; } + void System.Collections.IEnumerator.Reset() { } + } + } + public partial class X509Chain : System.IDisposable + { + public X509Chain() { } + public X509Chain(bool useMachineContext) { } + [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] + public X509Chain(System.IntPtr chainContext) { } + public System.IntPtr ChainContext { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509ChainElementCollection ChainElements { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509ChainPolicy ChainPolicy { get { throw null; } set { } } + public System.Security.Cryptography.X509Certificates.X509ChainStatus[] ChainStatus { get { throw null; } } + public Microsoft.Win32.SafeHandles.SafeX509ChainHandle? SafeHandle { get { throw null; } } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public bool Build(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { throw null; } + public static System.Security.Cryptography.X509Certificates.X509Chain Create() { throw null; } + public void Dispose() { } + protected virtual void Dispose(bool disposing) { } + public void Reset() { } + } + public partial class X509ChainElement + { + internal X509ChainElement() { } + public System.Security.Cryptography.X509Certificates.X509Certificate2 Certificate { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509ChainStatus[] ChainElementStatus { get { throw null; } } + public string Information { get { throw null; } } + } + public sealed partial class X509ChainElementCollection : System.Collections.Generic.IEnumerable, System.Collections.ICollection, System.Collections.IEnumerable + { + internal X509ChainElementCollection() { } + public int Count { get { throw null; } } + public bool IsSynchronized { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509ChainElement this[int index] { get { throw null; } } + public object SyncRoot { get { throw null; } } + public void CopyTo(System.Security.Cryptography.X509Certificates.X509ChainElement[] array, int index) { } + public System.Security.Cryptography.X509Certificates.X509ChainElementEnumerator GetEnumerator() { throw null; } + System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } + void System.Collections.ICollection.CopyTo(System.Array array, int index) { } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } + } + public sealed partial class X509ChainElementEnumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable + { + internal X509ChainElementEnumerator() { } + public System.Security.Cryptography.X509Certificates.X509ChainElement Current { get { throw null; } } + object System.Collections.IEnumerator.Current { get { throw null; } } + public bool MoveNext() { throw null; } + public void Reset() { } + void System.IDisposable.Dispose() { } + } + public sealed partial class X509ChainPolicy + { + public X509ChainPolicy() { } + public System.Security.Cryptography.OidCollection ApplicationPolicy { get { throw null; } } + public System.Security.Cryptography.OidCollection CertificatePolicy { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509Certificate2Collection CustomTrustStore { get { throw null; } } + public bool DisableCertificateDownloads { get { throw null; } set { } } + public System.Security.Cryptography.X509Certificates.X509Certificate2Collection ExtraStore { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509RevocationFlag RevocationFlag { get { throw null; } set { } } + public System.Security.Cryptography.X509Certificates.X509RevocationMode RevocationMode { get { throw null; } set { } } + public System.Security.Cryptography.X509Certificates.X509ChainTrustMode TrustMode { get { throw null; } set { } } + public System.TimeSpan UrlRetrievalTimeout { get { throw null; } set { } } + public System.Security.Cryptography.X509Certificates.X509VerificationFlags VerificationFlags { get { throw null; } set { } } + public System.DateTime VerificationTime { get { throw null; } set { } } + public void Reset() { } + } + public partial struct X509ChainStatus + { + private object _dummy; + private int _dummyPrimitive; + public System.Security.Cryptography.X509Certificates.X509ChainStatusFlags Status { readonly get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] + public string StatusInformation { get { throw null; } set { } } + } + [System.FlagsAttribute] + public enum X509ChainStatusFlags + { + NoError = 0, + NotTimeValid = 1, + NotTimeNested = 2, + Revoked = 4, + NotSignatureValid = 8, + NotValidForUsage = 16, + UntrustedRoot = 32, + RevocationStatusUnknown = 64, + Cyclic = 128, + InvalidExtension = 256, + InvalidPolicyConstraints = 512, + InvalidBasicConstraints = 1024, + InvalidNameConstraints = 2048, + HasNotSupportedNameConstraint = 4096, + HasNotDefinedNameConstraint = 8192, + HasNotPermittedNameConstraint = 16384, + HasExcludedNameConstraint = 32768, + PartialChain = 65536, + CtlNotTimeValid = 131072, + CtlNotSignatureValid = 262144, + CtlNotValidForUsage = 524288, + HasWeakSignature = 1048576, + OfflineRevocation = 16777216, + NoIssuanceChainPolicy = 33554432, + ExplicitDistrust = 67108864, + HasNotSupportedCriticalExtension = 134217728, + } + public enum X509ChainTrustMode + { + System = 0, + CustomRootTrust = 1, + } + public enum X509ContentType + { + Unknown = 0, + Cert = 1, + SerializedCert = 2, + Pfx = 3, + Pkcs12 = 3, + SerializedStore = 4, + Pkcs7 = 5, + Authenticode = 6, + } + public sealed partial class X509EnhancedKeyUsageExtension : System.Security.Cryptography.X509Certificates.X509Extension + { + public X509EnhancedKeyUsageExtension() { } + public X509EnhancedKeyUsageExtension(System.Security.Cryptography.AsnEncodedData encodedEnhancedKeyUsages, bool critical) { } + public X509EnhancedKeyUsageExtension(System.Security.Cryptography.OidCollection enhancedKeyUsages, bool critical) { } + public System.Security.Cryptography.OidCollection EnhancedKeyUsages { get { throw null; } } + public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } + } + public partial class X509Extension : System.Security.Cryptography.AsnEncodedData + { + protected X509Extension() { } + public X509Extension(System.Security.Cryptography.AsnEncodedData encodedExtension, bool critical) { } + public X509Extension(System.Security.Cryptography.Oid oid, byte[] rawData, bool critical) { } + public X509Extension(System.Security.Cryptography.Oid oid, System.ReadOnlySpan rawData, bool critical) { } + public X509Extension(string oid, byte[] rawData, bool critical) { } + public X509Extension(string oid, System.ReadOnlySpan rawData, bool critical) { } + public bool Critical { get { throw null; } set { } } + public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } + } + public sealed partial class X509ExtensionCollection : System.Collections.Generic.IEnumerable, System.Collections.ICollection, System.Collections.IEnumerable + { + public X509ExtensionCollection() { } + public int Count { get { throw null; } } + public bool IsSynchronized { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509Extension this[int index] { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509Extension? this[string oid] { get { throw null; } } + public object SyncRoot { get { throw null; } } + public int Add(System.Security.Cryptography.X509Certificates.X509Extension extension) { throw null; } + public void CopyTo(System.Security.Cryptography.X509Certificates.X509Extension[] array, int index) { } + public System.Security.Cryptography.X509Certificates.X509ExtensionEnumerator GetEnumerator() { throw null; } + System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } + void System.Collections.ICollection.CopyTo(System.Array array, int index) { } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } + } + public sealed partial class X509ExtensionEnumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable + { + internal X509ExtensionEnumerator() { } + public System.Security.Cryptography.X509Certificates.X509Extension Current { get { throw null; } } + object System.Collections.IEnumerator.Current { get { throw null; } } + public bool MoveNext() { throw null; } + public void Reset() { } + void System.IDisposable.Dispose() { } + } + public enum X509FindType + { + FindByThumbprint = 0, + FindBySubjectName = 1, + FindBySubjectDistinguishedName = 2, + FindByIssuerName = 3, + FindByIssuerDistinguishedName = 4, + FindBySerialNumber = 5, + FindByTimeValid = 6, + FindByTimeNotYetValid = 7, + FindByTimeExpired = 8, + FindByTemplateName = 9, + FindByApplicationPolicy = 10, + FindByCertificatePolicy = 11, + FindByExtension = 12, + FindByKeyUsage = 13, + FindBySubjectKeyIdentifier = 14, + } + public enum X509IncludeOption + { + None = 0, + ExcludeRoot = 1, + EndCertOnly = 2, + WholeChain = 3, + } + [System.FlagsAttribute] + public enum X509KeyStorageFlags + { + DefaultKeySet = 0, + UserKeySet = 1, + MachineKeySet = 2, + Exportable = 4, + UserProtected = 8, + PersistKeySet = 16, + EphemeralKeySet = 32, + } + public sealed partial class X509KeyUsageExtension : System.Security.Cryptography.X509Certificates.X509Extension + { + public X509KeyUsageExtension() { } + public X509KeyUsageExtension(System.Security.Cryptography.AsnEncodedData encodedKeyUsage, bool critical) { } + public X509KeyUsageExtension(System.Security.Cryptography.X509Certificates.X509KeyUsageFlags keyUsages, bool critical) { } + public System.Security.Cryptography.X509Certificates.X509KeyUsageFlags KeyUsages { get { throw null; } } + public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } + } + [System.FlagsAttribute] + public enum X509KeyUsageFlags + { + None = 0, + EncipherOnly = 1, + CrlSign = 2, + KeyCertSign = 4, + KeyAgreement = 8, + DataEncipherment = 16, + KeyEncipherment = 32, + NonRepudiation = 64, + DigitalSignature = 128, + DecipherOnly = 32768, + } + public enum X509NameType + { + SimpleName = 0, + EmailName = 1, + UpnName = 2, + DnsName = 3, + DnsFromAlternativeName = 4, + UrlName = 5, + } + public enum X509RevocationFlag + { + EndCertificateOnly = 0, + EntireChain = 1, + ExcludeRoot = 2, + } + public enum X509RevocationMode + { + NoCheck = 0, + Online = 1, + Offline = 2, + } + public abstract partial class X509SignatureGenerator + { + protected X509SignatureGenerator() { } + public System.Security.Cryptography.X509Certificates.PublicKey PublicKey { get { throw null; } } + protected abstract System.Security.Cryptography.X509Certificates.PublicKey BuildPublicKey(); + public static System.Security.Cryptography.X509Certificates.X509SignatureGenerator CreateForECDsa(System.Security.Cryptography.ECDsa key) { throw null; } + public static System.Security.Cryptography.X509Certificates.X509SignatureGenerator CreateForRSA(System.Security.Cryptography.RSA key, System.Security.Cryptography.RSASignaturePadding signaturePadding) { throw null; } + public abstract byte[] GetSignatureAlgorithmIdentifier(System.Security.Cryptography.HashAlgorithmName hashAlgorithm); + public abstract byte[] SignData(byte[] data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm); + } + public sealed partial class X509Store : System.IDisposable + { + public X509Store() { } + public X509Store(System.IntPtr storeHandle) { } + public X509Store(System.Security.Cryptography.X509Certificates.StoreLocation storeLocation) { } + public X509Store(System.Security.Cryptography.X509Certificates.StoreName storeName) { } + public X509Store(System.Security.Cryptography.X509Certificates.StoreName storeName, System.Security.Cryptography.X509Certificates.StoreLocation storeLocation) { } + public X509Store(System.Security.Cryptography.X509Certificates.StoreName storeName, System.Security.Cryptography.X509Certificates.StoreLocation storeLocation, System.Security.Cryptography.X509Certificates.OpenFlags flags) { } + public X509Store(string storeName) { } + public X509Store(string storeName, System.Security.Cryptography.X509Certificates.StoreLocation storeLocation) { } + public X509Store(string storeName, System.Security.Cryptography.X509Certificates.StoreLocation storeLocation, System.Security.Cryptography.X509Certificates.OpenFlags flags) { } + public System.Security.Cryptography.X509Certificates.X509Certificate2Collection Certificates { get { throw null; } } + public bool IsOpen { get { throw null; } } + public System.Security.Cryptography.X509Certificates.StoreLocation Location { get { throw null; } } + public string? Name { get { throw null; } } + public System.IntPtr StoreHandle { get { throw null; } } + public void Add(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } + public void AddRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } + public void Close() { } + public void Dispose() { } + public void Open(System.Security.Cryptography.X509Certificates.OpenFlags flags) { } + public void Remove(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) { } + public void RemoveRange(System.Security.Cryptography.X509Certificates.X509Certificate2Collection certificates) { } + } + public sealed partial class X509SubjectKeyIdentifierExtension : System.Security.Cryptography.X509Certificates.X509Extension + { + public X509SubjectKeyIdentifierExtension() { } + public X509SubjectKeyIdentifierExtension(byte[] subjectKeyIdentifier, bool critical) { } + public X509SubjectKeyIdentifierExtension(System.ReadOnlySpan subjectKeyIdentifier, bool critical) { } + public X509SubjectKeyIdentifierExtension(System.Security.Cryptography.AsnEncodedData encodedSubjectKeyIdentifier, bool critical) { } + public X509SubjectKeyIdentifierExtension(System.Security.Cryptography.X509Certificates.PublicKey key, bool critical) { } + public X509SubjectKeyIdentifierExtension(System.Security.Cryptography.X509Certificates.PublicKey key, System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical) { } + public X509SubjectKeyIdentifierExtension(string subjectKeyIdentifier, bool critical) { } + public string? SubjectKeyIdentifier { get { throw null; } } + public override void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { } + } + public enum X509SubjectKeyIdentifierHashAlgorithm + { + Sha1 = 0, + ShortSha1 = 1, + CapiSha1 = 2, + } + [System.FlagsAttribute] + public enum X509VerificationFlags + { + NoFlag = 0, + IgnoreNotTimeValid = 1, + IgnoreCtlNotTimeValid = 2, + IgnoreNotTimeNested = 4, + IgnoreInvalidBasicConstraints = 8, + AllowUnknownCertificateAuthority = 16, + IgnoreWrongUsage = 32, + IgnoreInvalidName = 64, + IgnoreInvalidPolicy = 128, + IgnoreEndRevocationUnknown = 256, + IgnoreCtlSignerRevocationUnknown = 512, + IgnoreCertificateAuthorityRevocationUnknown = 1024, + IgnoreRootRevocationUnknown = 2048, + AllFlags = 4095, + } } diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.csproj b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.csproj index 3baaa77d1f5156..0b9ddef821dad2 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.csproj +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.csproj @@ -2,11 +2,15 @@ $(NetCoreAppCurrent) enable + $(NoWarn);SYSLIB0026 + + + diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs b/src/libraries/System.Security.Cryptography/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.Cng/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs rename to src/libraries/System.Security.Cryptography/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs index 28508857bc2b8c..9808e723e2a0bc 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs +++ b/src/libraries/System.Security.Cryptography/src/Microsoft/Win32/SafeHandles/NCryptSafeHandles.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using ErrorCode = Interop.NCrypt.ErrorCode; @@ -65,11 +66,12 @@ private enum OwnershipState private SafeHandle? _parentHandle; + [SupportedOSPlatform("windows")] protected SafeNCryptHandle() : base(true) { - return; } + [SupportedOSPlatform("windows")] protected SafeNCryptHandle(IntPtr handle, SafeHandle parentHandle) : base(true) { @@ -346,10 +348,12 @@ internal bool ReleaseNativeWithNCryptFreeObject() /// public sealed class SafeNCryptKeyHandle : SafeNCryptHandle { + [SupportedOSPlatform("windows")] public SafeNCryptKeyHandle() { } + [SupportedOSPlatform("windows")] public SafeNCryptKeyHandle(IntPtr handle, SafeHandle parentHandle) : base(handle, parentHandle) { @@ -371,6 +375,9 @@ protected override bool ReleaseNativeHandle() /// public sealed class SafeNCryptProviderHandle : SafeNCryptHandle { + [SupportedOSPlatform("windows")] + public SafeNCryptProviderHandle() { } + internal SafeNCryptProviderHandle Duplicate() { return Duplicate(); @@ -396,6 +403,9 @@ protected override bool ReleaseNativeHandle() /// public sealed class SafeNCryptSecretHandle : SafeNCryptHandle { + [SupportedOSPlatform("windows")] + public SafeNCryptSecretHandle() { } + protected override bool ReleaseNativeHandle() { return ReleaseNativeWithNCryptFreeObject(); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Microsoft/Win32/SafeHandles/SafePasswordHandle.cs b/src/libraries/System.Security.Cryptography/src/Microsoft/Win32/SafeHandles/SafePasswordHandle.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Microsoft/Win32/SafeHandles/SafePasswordHandle.cs rename to src/libraries/System.Security.Cryptography/src/Microsoft/Win32/SafeHandles/SafePasswordHandle.cs diff --git a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index dc30b357b0b388..02431e49a9bd4d 100644 --- a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -60,15 +60,45 @@ Error occurred during a cryptographic operation. + + Array may not be empty or null. + + + String cannot be empty or null. + + + The '{0}' string cannot be empty or null. + + + Illegal enum value: {0}. + + + Invalid handle. + + + Invalid type. + Only single dimensional arrays are supported for the requested action. Destination is too short. + + The method cannot be called with an invalid or closed SafeHandle. + + + Value of flags is invalid. + + + The value of 'nameType' is invalid. + Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. + + The OID value was invalid. + Range of random number does not contain at least one possibility. @@ -111,6 +141,18 @@ Positive number required. + + An empty custom trust store is not supported on this platform. + + + The certificate has invalid policy. + + + The certificate chain is incomplete. + + + The certificate's revocation status could not be determined. + Accessing a hash algorithm by manipulating the HashName property is not supported on this platform. Instead, you must instantiate one of the supplied subtypes (such as HMACSHA1.) @@ -126,24 +168,75 @@ Algorithms added to CryptoConfig must be accessible from outside their assembly. + + Keys used with the DSACng algorithm must have an algorithm group of DSA. + The keys from both parties must be the same size to generate a secret agreement. Keys used with the ECDiffieHellmanCng algorithm must have an algorithm group of ECDiffieHellman. + + Keys used with the ECDsaCng algorithm must have an algorithm group of ECDsa. + + + Keys used with the RSACng algorithm must have an algorithm group of RSA. + The computed authentication tag did not match the input authentication tag. The provided value of {0} bytes does not match the expected size of {1} bytes for the algorithm ({2}). + + '{0}' requires Windows Cryptographic API (CAPI), which is not available on this platform. + + + The certificate already has an associated private key. + + + The issuer certificate public key algorithm ({0}) does not match the value for this certificate request ({1}), use the X509SignatureGenerator overload. + + + The issuer certificate does not have a Basic Constraints extension. + + + The provided notBefore value is later than the notAfter value. + + + An X509Extension with OID '{0}' has already been specified. + + + The issuer certificate does not have an appropriate value for the Basic Constraints extension. + + + The issuer certificate's Key Usage extension is present but does not contain the KeyCertSign flag. + + + The provided issuer certificate does not have an associated private key. + + + This method cannot be used since no signing key was provided via a constructor, use an overload accepting an X509SignatureGenerator instead. + + + The requested notAfter value ({0}) is later than issuerCertificate.NotAfter ({1}). + + + The requested notBefore value ({0}) is earlier than issuerCertificate.NotBefore ({1}). + + + The issuer certificate uses an RSA key but no RSASignaturePadding was provided to a constructor. If one cannot be provided, use the X509SignatureGenerator overload. + The specified feedback size '{0}' for CipherMode '{1}' is not supported. The specified CipherMode '{0}' is not supported. + + This key is for algorithm '{0}'. Expected '{1}'. + Encoded OID length is too large (greater than 0x7f bytes). @@ -153,9 +246,18 @@ Object contains only the public half of a key pair. A private key must also be provided. + + The requested key container was not found. + + + The specified cryptographic service provider (CSP) does not support this key algorithm: {0}. + The specified curve '{0}' or its parameters are not valid for this platform. + + Custom trust certificates were provided while in System trust mode. + This platform does not allow the automatic selection of an algorithm. @@ -180,6 +282,9 @@ The current platform does not support the specified feedback size. + + Unable to get file status. + No hash algorithm has been associated with this formatter object, assign one via the SetHashAlgorithm method. @@ -201,12 +306,18 @@ Specified cipher mode is not valid for this algorithm. + + The chain context handle is invalid. + The specified key parameters are not valid. Q.X and Q.Y, or D, must be specified. Q.X, Q.Y must be the same length. If D is specified it must be the same length as Q.X and Q.Y if also specified for named curves or the same length as Order for explicit curves. The specified Oid ({0}) is not valid. The Oid.FriendlyName or Oid.Value property must be set. + + Invalid directory permissions. The directory '{0}' must be readable, writable and executable by the owner. + The specified DSA parameters are not valid; P, G and Y must be the same length (the key size). @@ -228,6 +339,9 @@ The specified DSA parameters are not valid; Seed, if present, must be 20 bytes long for keys shorter than 1024 bits. + + Length of the DSA signature was not 40 bytes. + The specified Characteristic2 curve parameters are not valid. Polynomial, A, B, G.X, G.Y, and Order are required. A, B, G.X, G.Y must be the same length, and the same length as Q.X, Q.Y and D if those are specified. Cofactor is required. Seed and Hash are optional. Other parameters are not allowed. @@ -240,12 +354,21 @@ Specified feedback size is not valid for this algorithm. + + Invalid file permissions. The file '{0}' must readable and writable by the current owner and by no one else, and the permissions could not be changed to meet that criteria. + Input string does not contain a valid encoding of the '{0}' '{1}' parameter. + + {0} is an invalid handle. + The specified OID ({0}) does not represent a known hash algorithm. + + {0} algorithm hash size is {1} bytes. + Specified initialization vector (IV) does not match the block size for this algorithm. @@ -264,18 +387,33 @@ Object identifier (OID) is unknown. + + This operation is not supported for this class. + Padding is invalid and cannot be removed. Specified padding mode is not valid for this algorithm. - - This operation is not supported for this class. + + The store handle is invalid. The specified tag is not a valid size for this algorithm. + + A null or disposed certificate was present in CustomTrustStore. + + + The string contains a character not in the 7 bit ASCII character set. + + + The string contains an invalid X500 name attribute key, oid, value or delimiter. + + + Key Blob not in expected format. + The key is too small for the requested operation. @@ -321,12 +459,39 @@ Output keying material length can be at most {0} bytes (255 * hash length). + + The CNG key handle being opened was detected to be ephemeral, but the EphemeralKey open option was not specified. + Cannot open an invalid handle. + + The owner of '{0}' is not the current user. + The input data is not a complete block. + + Algorithm is unavailable or is not supported for this operation. + + + The Initialization vector should have the same length as the algorithm block size in bytes. + + + Requested number of bytes exceeds the maximum. + + + Value of '{0}' cannot be changed after the bytes have been retrieved. + + + A certificate referenced a private key which was already referenced, or could not be loaded. + + + The certificate data cannot be read with the provided password, the password may be incorrect. + + + The provided PFX data contains no certificates. + The EncryptedPrivateKeyInfo structure was decoded but was not successfully interpreted, the password may be incorrect. @@ -336,6 +501,12 @@ The specified plaintext size is too large. + + The provided key does not match the public key for this certificate. + + + The provided key does not match the public key algorithm for this certificate. + The pseudo-random key length must be at least {0} bytes. @@ -363,15 +534,42 @@ The TLS key derivation function requires a seed value of exactly 64 bytes. + + The TLS key derivation function requires both the label and seed properties to be set. + CNG provider unexpectedly terminated encryption or decryption prematurely. + + The Disallowed store is not supported on this platform, but already has data. All files under '{0}' must be removed. + + + Unix LocalMachine X509Stores are read-only for all users. + + + Unix LocalMachine X509Store is limited to the Root and CertificateAuthority stores. + + + The Disallowed store is not supported on this platform. + + + The {0} value cannot be set on Unix. + + + X509ContentType.SerializedCert and X509ContentType.SerializedStore are not supported on Unix. + The algorithm identified by '{0}' is unknown, not valid for the requested usage, or was not handled. + + The certificate content type could not be determined. + '{0}' is not a known hash algorithm. + + '{0}' is not a known key algorithm. + Unknown padding mode used. @@ -384,15 +582,117 @@ The specified PaddingMode is not supported. + + Certificate '{0}' is corrupted. + + + The certificate export operation failed. + + + The parameter should be an X509Extension. + + + Invalid content type. + + + Invalid find type. + + + Invalid find value. + + + The flags '{0}' may not be specified together. + + + This platform does not support loading with EphemeralKeySet. Remove the flag to allow keys to be temporarily created on disk. + + + The key contents do not contain a PEM, the content is malformed, or the key does not match the certificate. + + + The certificate contents do not contain a PEM with a CERTIFICATE label, or the content is malformed. + + + Cannot find the original signer. + + + PKCS#7 certificate format is not supported on this platform. + + + The PKCS#12 Exportable flag is not supported on this platform. + + + The PKCS#12 PersistKeySet flag is not supported on this platform. + + + Root certificate store is not supported on this platform. + + + The X509 certificate could not be added to the store. + + + The platform does not have a definition for an X509 certificate store named '{0}' with a StoreLocation of '{1}', and does not support creating it. + + + Adding a DSA private key to the store is not supported on this platform. + + + Failed to enumerate certificates from the store. + + + The X509 certificate could not be added to the store because all candidate file names were in use. + + + The specified X509 certificate store does not exist. + + + The X509 certificate store has not been opened. + + + The X509 certificate store is read-only. + + + The X509 certificate could not be removed from the store. + + + Removing the requested certificate would modify admin trust settings, and has been denied. + + + Removing the requested certificate would modify user trust settings, and has been denied. + + + CryptSetKeyParam failed with error code {0}. + + + CSPParameters cannot be null + Setting the hashname after it's already been set is not supported on this platform. + + Enumeration has not started. Call MoveNext. + The algorithm's implementation is incorrect. The algorithm's block size is not supported. + + CryptoApi ECDsa keys are not supported. + + + CryptoApi ECDiffieHellman keys are not supported. + + + X509Certificate is immutable on this platform. Use the equivalent constructor instead. + + + The certificate key algorithm is not supported. + + + The X509 Basic Constraints extension with OID 2.5.29.10 is not supported. + Method not supported. @@ -408,7 +708,28 @@ Stream does not support writing. + + The home directory of the current user could not be determined. + + + Windows Cryptography Next Generation (CNG) is not supported on this platform. + + + OpenSSL is not supported on this platform. + + + Access is denied. + + + The {0} value was invalid. + System.Security.Cryptography is not supported on this platform. + + System.Security.Cryptography.X509Certificates is not supported on this platform. + + + Unknown error. + diff --git a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj index a2a2d2d52ca21c..073513a0de966d 100644 --- a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj +++ b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj @@ -8,6 +8,7 @@ SR.SystemSecurityCryptography_PlatformNotSupported + $(NoWarn);SYSLIB0026 true @@ -27,6 +28,8 @@ Link="Common\Internal\Cryptography\HashProvider.cs" /> + + + Common\System\Security\Cryptography\Asn1\AttributeAsn.xml.cs Common\System\Security\Cryptography\Asn1\AttributeAsn.xml + + Common\System\Security\Cryptography\Asn1\AttributeAsn.manual.cs + Common\System\Security\Cryptography\Asn1\AttributeAsn.xml + Common\System\Security\Cryptography\Asn1\CurveAsn.xml @@ -72,6 +83,13 @@ Common\System\Security\Cryptography\Asn1\CurveAsn.xml.cs Common\System\Security\Cryptography\Asn1\CurveAsn.xml + + Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml + + + Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml.cs + Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml + Common\System\Security\Cryptography\Asn1\DssParms.xml @@ -93,6 +111,13 @@ Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml.cs Common\System\Security\Cryptography\Asn1\ECPrivateKey.xml + + Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml + + + Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml.cs + Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml + Common\System\Security\Cryptography\Asn1\EncryptedPrivateKeyInfoAsn.xml @@ -107,6 +132,20 @@ Common\System\Security\Cryptography\Asn1\FieldID.xml.cs Common\System\Security\Cryptography\Asn1\FieldID.xml + + Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml + + + Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml.cs + Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml + + + Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml + + + Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml.cs + Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml + Common\System\Security\Cryptography\Asn1\PBEParameter.xml @@ -142,6 +181,13 @@ Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml.cs Common\System\Security\Cryptography\Asn1\PrivateKeyInfoAsn.xml + + Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml + + + Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml.cs + Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml + Common\System\Security\Cryptography\Asn1\Rc2CbcParameters.xml @@ -181,6 +227,17 @@ Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml.cs Common\System\Security\Cryptography\Asn1\SubjectPublicKeyInfoAsn.xml + + Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.xml + + + Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.xml.cs + Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.xml + + + Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.manual.cs + Common\System\Security\Cryptography\Asn1\X509ExtensionAsn.xml + + + @@ -234,6 +293,21 @@ + + + + + + + + + + + + + + + @@ -241,6 +315,8 @@ + + @@ -256,10 +332,12 @@ + + @@ -275,18 +353,22 @@ + + + + @@ -301,6 +383,7 @@ + @@ -315,47 +398,139 @@ + + + + - - - - Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml - - - Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml.cs - Common\System\Security\Cryptography\Asn1\DirectoryStringAsn.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + System\Security\Cryptography\X509Certificates\Asn1\BasicConstraintsAsn.xml - - Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml.cs - Common\System\Security\Cryptography\Asn1\EdiPartyNameAsn.xml + + + System\Security\Cryptography\X509Certificates\Asn1\CertificateAsn.xml - - Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml - - - Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml.cs - Common\System\Security\Cryptography\Asn1\GeneralNameAsn.xml + + + System\Security\Cryptography\X509Certificates\Asn1\CertificationRequestAsn.xml - - Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml - - - Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml.cs - Common\System\Security\Cryptography\Asn1\OtherNameAsn.xml + + + System\Security\Cryptography\X509Certificates\Asn1\CertificationRequestInfoAsn.xml + + + + + System\Security\Cryptography\X509Certificates\Asn1\TbsCertificateAsn.xml + + + + + System\Security\Cryptography\X509Certificates\Asn1\TimeAsn.xml + + + + + System\Security\Cryptography\X509Certificates\Asn1\ValidityAsn.xml + + + + + System\Security\Cryptography\X509Certificates\Asn1\AccessDescriptionAsn.xml + + + + System\Security\Cryptography\X509Certificates\Asn1\CertificatePolicyMappingAsn.xml + + + + System\Security\Cryptography\X509Certificates\Asn1\CertificateTemplateAsn.xml + + + + System\Security\Cryptography\X509Certificates\Asn1\PolicyConstraintsAsn.xml + + + + System\Security\Cryptography\X509Certificates\Asn1\PolicyInformationAsn.xml - - + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml.cs + Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.manual.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml + + + + + + + + + + + + + + + + + + + + + + + + + - + + + System\Security\Cryptography\X509Certificates\Asn1\DistributionPointAsn.xml + + + + System\Security\Cryptography\X509Certificates\Asn1\DistributionPointNameAsn.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + @@ -558,23 +922,120 @@ Link="Common\System\Security\Cryptography\ECDsaAndroid.cs" /> + + Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml.cs + Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.manual.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml.cs + Common\System\Security\Cryptography\Asn1\DigestInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\CertBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\MacData.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.manual.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\PfxAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs12\SafeBagAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs7\ContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedContentInfoAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml + + + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml.cs + Common\System\Security\Cryptography\Asn1\Pkcs7\EncryptedDataAsn.xml + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Link="Common\System\Security\Cryptography\ECDiffieHellmanCng.cs" /> + Link="Common\System\Security\Cryptography\ECDiffieHellmanCng.ImportExport.cs" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + @@ -861,6 +1823,10 @@ + + + + diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/AesCng.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCng.Windows.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/AesCng.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCng.Windows.cs index 297cd511688889..19046e7bdf3287 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/AesCng.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCng.Windows.cs @@ -8,6 +8,7 @@ // that each of these derive from a different class, it can't be helped. // +using System.Runtime.Versioning; using Internal.Cryptography; using Internal.NativeCrypto; @@ -15,21 +16,25 @@ namespace System.Security.Cryptography { public sealed class AesCng : Aes, ICngSymmetricAlgorithm { + [SupportedOSPlatform("windows")] public AesCng() { _core = new CngSymmetricAlgorithmCore(this); } + [SupportedOSPlatform("windows")] public AesCng(string keyName) : this(keyName, CngProvider.MicrosoftSoftwareKeyStorageProvider) { } + [SupportedOSPlatform("windows")] public AesCng(string keyName, CngProvider provider) : this(keyName, provider, CngKeyOpenOptions.None) { } + [SupportedOSPlatform("windows")] public AesCng(string keyName, CngProvider provider, CngKeyOpenOptions openOptions) { _core = new CngSymmetricAlgorithmCore(this, keyName, provider, openOptions); @@ -244,7 +249,7 @@ SafeAlgorithmHandle ICngSymmetricAlgorithm.GetEphemeralModeHandle(CipherMode mod string ICngSymmetricAlgorithm.GetNCryptAlgorithmIdentifier() { - return Interop.NCrypt.NCRYPT_AES_ALGORITHM; + return Cng.BCRYPT_AES_ALGORITHM; } byte[] ICngSymmetricAlgorithm.PreprocessKey(byte[] key) diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/AesCryptoServiceProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCryptoServiceProvider.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/AesCryptoServiceProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCryptoServiceProvider.cs index c879a4f5460870..2e081e8a064939 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/AesCryptoServiceProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesCryptoServiceProvider.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; +using System.Runtime.Versioning; namespace System.Security.Cryptography { @@ -11,6 +12,7 @@ public sealed class AesCryptoServiceProvider : Aes { private readonly Aes _impl; + [UnsupportedOSPlatform("browser")] public AesCryptoServiceProvider() { // This class wraps Aes diff --git a/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/BasicSymmetricCipherCsp.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/BasicSymmetricCipherCsp.cs similarity index 90% rename from src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/BasicSymmetricCipherCsp.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/BasicSymmetricCipherCsp.cs index 5d97658ab644cf..0ecad1312e15f6 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/BasicSymmetricCipherCsp.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/BasicSymmetricCipherCsp.cs @@ -1,20 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; -using System.Security.Cryptography; -using Internal.NativeCrypto; -using Microsoft.Win32.SafeHandles; -using static Internal.NativeCrypto.CapiHelper; +using Internal.Cryptography; +using static System.Security.Cryptography.CapiHelper; -namespace Internal.Cryptography +namespace System.Security.Cryptography { internal sealed class BasicSymmetricCipherCsp : BasicSymmetricCipher { private readonly bool _encrypting; private SafeProvHandle _hProvider; - private SafeKeyHandle _hKey; + private SafeCapiKeyHandle _hKey; public BasicSymmetricCipherCsp(int algId, CipherMode cipherMode, int blockSizeInBytes, byte[] key, bool addNoSaltFlag, byte[]? iv, bool encrypting, int feedbackSize, int paddingSizeInBytes) : base(cipherMode.GetCipherIv(iv), blockSizeInBytes, paddingSizeInBytes) @@ -46,7 +43,7 @@ protected override void Dispose(bool disposing) { if (disposing) { - SafeKeyHandle hKey = _hKey; + SafeCapiKeyHandle hKey = _hKey; _hKey = null!; if (hKey != null) { @@ -110,9 +107,9 @@ private int Transform(ReadOnlySpan input, Span output, bool isFinal) return numBytesWritten; } - private static SafeKeyHandle ImportCspBlob(SafeProvHandle safeProvHandle, int algId, byte[] rawKey, bool addNoSaltFlag) + private static SafeCapiKeyHandle ImportCspBlob(SafeProvHandle safeProvHandle, int algId, byte[] rawKey, bool addNoSaltFlag) { - SafeKeyHandle safeKeyHandle; + SafeCapiKeyHandle safeKeyHandle; byte[] keyBlob = ToPlainTextKeyBlob(algId, rawKey); ImportKeyBlob(safeProvHandle, (CspProviderFlags)0, addNoSaltFlag, keyBlob, out safeKeyHandle); // Note if plain text import fails, .NET Framework falls back to "ExponentOfOneImport" which is not handled here diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/BasicSymmetricCipherNCrypt.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/BasicSymmetricCipherNCrypt.cs similarity index 85% rename from src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/BasicSymmetricCipherNCrypt.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/BasicSymmetricCipherNCrypt.cs index 1e38c44fef8fbb..ffe1c8fa13e674 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/BasicSymmetricCipherNCrypt.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/BasicSymmetricCipherNCrypt.cs @@ -1,17 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Security.Cryptography; using System.Text; +using Internal.Cryptography; +using Internal.NativeCrypto; using Microsoft.Win32.SafeHandles; using ErrorCode = Interop.NCrypt.ErrorCode; using AsymmetricPaddingMode = Interop.NCrypt.AsymmetricPaddingMode; -namespace Internal.Cryptography +namespace System.Security.Cryptography { internal sealed class BasicSymmetricCipherNCrypt : BasicSymmetricCipher { @@ -104,7 +103,7 @@ private void Reset() { if (IV != null) { - CngProperty prop = new CngProperty(Interop.NCrypt.NCRYPT_INITIALIZATION_VECTOR, IV, CngPropertyOptions.None); + CngProperty prop = new CngProperty(KeyPropertyName.InitializationVector, IV, CngPropertyOptions.None); _cngKey!.SetProperty(prop); } } @@ -113,10 +112,10 @@ private void Reset() private readonly bool _encrypting; private static readonly CngProperty s_ECBMode = - new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.Unicode.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_ECB + "\0"), CngPropertyOptions.None); + new CngProperty(KeyPropertyName.ChainingMode, Encoding.Unicode.GetBytes(Cng.BCRYPT_CHAIN_MODE_ECB + "\0"), CngPropertyOptions.None); private static readonly CngProperty s_CBCMode = - new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.Unicode.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_CBC + "\0"), CngPropertyOptions.None); + new CngProperty(KeyPropertyName.ChainingMode, Encoding.Unicode.GetBytes(Cng.BCRYPT_CHAIN_MODE_CBC + "\0"), CngPropertyOptions.None); private static readonly CngProperty s_CFBMode = - new CngProperty(Interop.NCrypt.NCRYPT_CHAINING_MODE_PROPERTY, Encoding.Unicode.GetBytes(Interop.BCrypt.BCRYPT_CHAIN_MODE_CFB + "\0"), CngPropertyOptions.None); + new CngProperty(KeyPropertyName.ChainingMode, Encoding.Unicode.GetBytes(Cng.BCRYPT_CHAIN_MODE_CFB + "\0"), CngPropertyOptions.None); } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Browser.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Browser.cs new file mode 100644 index 00000000000000..43c983085e1bd1 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Browser.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + internal static partial class CapiHelper + { + // Return PROV_RSA_AES, in case any compat case pops up. + internal const int DefaultRsaProviderType = 24; + } +} diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs index 67a22cd75d1162..2a4b6f14808367 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.DSA.Shared.cs @@ -1,12 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.IO; -using System.Security.Cryptography; -namespace Internal.NativeCrypto +namespace System.Security.Cryptography { internal static partial class CapiHelper { diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.DSA.Windows.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Windows.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.DSA.Windows.cs index 09c9f4c6988e20..9cef8555e573a3 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.DSA.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.DSA.Windows.cs @@ -1,11 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Security.Cryptography; -using Microsoft.Win32.SafeHandles; - -namespace Internal.NativeCrypto +namespace System.Security.Cryptography { internal static partial class CapiHelper { diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Shared.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Shared.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Shared.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Shared.cs index a75758092ef179..f6f9648f35aba0 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Shared.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Shared.cs @@ -2,11 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography; -using System; using System.IO; -using System.Security.Cryptography; -namespace Internal.NativeCrypto +namespace System.Security.Cryptography { internal static partial class CapiHelper { @@ -262,5 +260,19 @@ private static byte[] ReadReversed(this BinaryReader br, int count) Array.Reverse(data); return data; } + + internal static byte[]? TrimLargeIV(byte[]? currentIV, int blockSizeInBits) + { + int blockSizeBytes = checked((blockSizeInBits + 7) / 8); + + if (currentIV?.Length > blockSizeBytes) + { + byte[] tmp = new byte[blockSizeBytes]; + Buffer.BlockCopy(currentIV, 0, tmp, 0, tmp.Length); + return tmp; + } + + return currentIV; + } } } diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.SymmetricKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.SymmetricKey.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.SymmetricKey.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.SymmetricKey.cs index 6da826133d20d1..27cbf46b8f2a1e 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.SymmetricKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.SymmetricKey.cs @@ -3,7 +3,7 @@ using System.IO; -namespace Internal.NativeCrypto +namespace System.Security.Cryptography { internal static partial class CapiHelper { diff --git a/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/Unix/HashAlgorithmNames.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Unix.cs similarity index 76% rename from src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/Unix/HashAlgorithmNames.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Unix.cs index 9645cee8c61203..8fcf4603e95789 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/Internal/Cryptography/Unix/HashAlgorithmNames.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Unix.cs @@ -1,18 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Security.Cryptography; - -namespace Internal.Cryptography +namespace System.Security.Cryptography { - internal static class HashAlgorithmNames + internal static partial class CapiHelper { - public const string MD5 = "MD5"; - public const string SHA1 = "SHA1"; - public const string SHA256 = "SHA256"; - public const string SHA384 = "SHA384"; - public const string SHA512 = "SHA512"; + internal const string MD5 = "MD5"; + internal const string SHA1 = "SHA1"; + internal const string SHA256 = "SHA256"; + internal const string SHA384 = "SHA384"; + internal const string SHA512 = "SHA512"; private const string OID_MD5 = "1.2.840.113549.2.5"; private const string OID_SHA1 = "1.3.14.3.2.26"; @@ -21,7 +18,7 @@ internal static class HashAlgorithmNames private const string OID_SHA512 = "2.16.840.1.101.3.4.2.3"; // For backwards compat with CapiHelper.ObjToHashAlgorithm, use "hashAlg" as name - public static HashAlgorithmName ObjToHashAlgorithmName(object hashAlg) + internal static HashAlgorithmName ObjToHashAlgorithmName(object hashAlg) { if (hashAlg == null) throw new ArgumentNullException(nameof(hashAlg)); @@ -49,7 +46,7 @@ public static HashAlgorithmName ObjToHashAlgorithmName(object hashAlg) throw new ArgumentException(SR.Argument_InvalidValue); } - public static HashAlgorithmName NameOrOidToHashAlgorithmName(string nameOrOid) + internal static HashAlgorithmName NameOrOidToHashAlgorithmName(string nameOrOid) { HashAlgorithmName? name; @@ -78,7 +75,7 @@ public static HashAlgorithmName NameOrOidToHashAlgorithmName(string nameOrOid) /// /// Map HashAlgorithm type to HashAlgorithmName without using CryptoConfig. Returns null if not found. /// - public static HashAlgorithmName? ToHashAlgorithmName(this HashAlgorithm hashAlgorithm) + internal static HashAlgorithmName? ToHashAlgorithmName(this HashAlgorithm hashAlgorithm) { if (hashAlgorithm is SHA1) return HashAlgorithmName.SHA1; @@ -94,7 +91,7 @@ public static HashAlgorithmName NameOrOidToHashAlgorithmName(string nameOrOid) return null; } - public static HashAlgorithmName? OidToHashAlgorithmName(string oid) + internal static HashAlgorithmName? OidToHashAlgorithmName(string oid) { switch (oid) { @@ -113,7 +110,7 @@ public static HashAlgorithmName NameOrOidToHashAlgorithmName(string nameOrOid) } } - public static HashAlgorithmName? HashAlgorithmTypeToHashAlgorithmName(Type hashAlgType) + internal static HashAlgorithmName? HashAlgorithmTypeToHashAlgorithmName(Type hashAlgType) { if (typeof(SHA1).IsAssignableFrom(hashAlgType)) return HashAlgorithmName.SHA1; @@ -128,5 +125,16 @@ public static HashAlgorithmName NameOrOidToHashAlgorithmName(string nameOrOid) return null; } + + internal static CryptographicException GetBadDataException() + { + const int NTE_BAD_DATA = unchecked((int)CryptKeyError.NTE_BAD_DATA); + return new CryptographicException(NTE_BAD_DATA); + } + + internal static CryptographicException GetEFailException() + { + return new CryptographicException(E_FAIL); + } } } diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Windows.cs similarity index 93% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Windows.cs index 48c6a78764fa6f..591470ad24e922 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Windows.cs @@ -1,19 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers.Binary; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Text; using Internal.Cryptography; using Microsoft.Win32.SafeHandles; using static Interop.Crypt32; using CryptProvParam = Interop.Advapi32.CryptProvParam; -namespace Internal.NativeCrypto +namespace System.Security.Cryptography { /// /// Following part of CAPIHelper keeps the wrappers for all the PInvoke calls @@ -349,7 +347,7 @@ internal static int GetProviderParameterWorker(SafeProvHandle safeProvHandle, by { throw GetErrorCode().ToCryptographicException(); } - if (null != impType && cb == Constants.SIZE_OF_DWORD) + if (null != impType && cb == sizeof(uint)) { impTypeReturn = BitConverter.ToInt32(impType, 0); } @@ -360,12 +358,12 @@ internal static int GetProviderParameterWorker(SafeProvHandle safeProvHandle, by /// This method queries the key container and get some of it's properties. /// Those properties should never cause UI to display. /// - public static object GetProviderParameter(SafeProvHandle safeProvHandle, int keyNumber, int keyParam) + public static object GetProviderParameter(SafeProvHandle safeProvHandle, int keyNumber, ClrPropertyId keyParam) { VerifyValidHandle(safeProvHandle); - byte[] impType = new byte[Constants.SIZE_OF_DWORD]; - int cb = sizeof(byte) * Constants.SIZE_OF_DWORD; - SafeKeyHandle safeKeyHandle = SafeKeyHandle.InvalidHandle; + byte[] impType = new byte[sizeof(uint)]; + int cb = sizeof(byte) * sizeof(uint); + SafeCapiKeyHandle safeKeyHandle = SafeCapiKeyHandle.InvalidHandle; int impTypeReturn; int returnType = 0; //using 0 for bool and 1 for string return types bool retVal = false; @@ -375,7 +373,7 @@ public static object GetProviderParameter(SafeProvHandle safeProvHandle, int key { switch (keyParam) { - case Constants.CLR_EXPORTABLE: + case ClrPropertyId.CLR_EXPORTABLE: { impTypeReturn = GetProviderParameterWorker(safeProvHandle, impType, ref cb, CryptProvParam.PP_IMPTYPE); //If implementation type is not HW @@ -387,8 +385,8 @@ public static object GetProviderParameter(SafeProvHandle safeProvHandle, int key } byte[]? permissions = null; int permissionsReturn = 0; - permissions = new byte[Constants.SIZE_OF_DWORD]; - cb = sizeof(byte) * Constants.SIZE_OF_DWORD; + permissions = new byte[sizeof(uint)]; + cb = sizeof(byte) * sizeof(uint); if (!Interop.Advapi32.CryptGetKeyParam(safeKeyHandle, Interop.Advapi32.CryptGetKeyParamFlags.KP_PERMISSIONS, permissions, ref cb, 0)) { throw GetErrorCode().ToCryptographicException(); @@ -404,25 +402,25 @@ public static object GetProviderParameter(SafeProvHandle safeProvHandle, int key break; } - case Constants.CLR_REMOVABLE: + case ClrPropertyId.CLR_REMOVABLE: { impTypeReturn = GetProviderParameterWorker(safeProvHandle, impType, ref cb, CryptProvParam.PP_IMPTYPE); retVal = IsFlagBitSet((uint)impTypeReturn, (uint)CryptGetProvParamPPImpTypeFlags.CRYPT_IMPL_REMOVABLE); break; } - case Constants.CLR_HARDWARE: - case Constants.CLR_PROTECTED: + case ClrPropertyId.CLR_HARDWARE: + case ClrPropertyId.CLR_PROTECTED: { impTypeReturn = GetProviderParameterWorker(safeProvHandle, impType, ref cb, CryptProvParam.PP_IMPTYPE); retVal = IsFlagBitSet((uint)impTypeReturn, (uint)CryptGetProvParamPPImpTypeFlags.CRYPT_IMPL_HARDWARE); break; } - case Constants.CLR_ACCESSIBLE: + case ClrPropertyId.CLR_ACCESSIBLE: { retVal = CryptGetUserKey(safeProvHandle, keyNumber, out safeKeyHandle) ? true : false; break; } - case Constants.CLR_UNIQUE_CONTAINER: + case ClrPropertyId.CLR_UNIQUE_CONTAINER: { returnType = 1; byte[]? pb = null; @@ -454,7 +452,7 @@ public static object GetProviderParameter(SafeProvHandle safeProvHandle, int key /// /// Retrieves the handle for user public / private key pair. /// - internal static int GetUserKey(SafeProvHandle safeProvHandle, int keySpec, out SafeKeyHandle safeKeyHandle) + internal static int GetUserKey(SafeProvHandle safeProvHandle, int keySpec, out SafeCapiKeyHandle safeKeyHandle) { int hr = S_OK; VerifyValidHandle(safeProvHandle); @@ -472,7 +470,7 @@ internal static int GetUserKey(SafeProvHandle safeProvHandle, int keySpec, out S /// /// Generates the key if provided CSP handle is valid /// - internal static int GenerateKey(SafeProvHandle safeProvHandle, int algID, int flags, uint keySize, out SafeKeyHandle safeKeyHandle) + internal static int GenerateKey(SafeProvHandle safeProvHandle, int algID, int flags, uint keySize, out SafeCapiKeyHandle safeKeyHandle) { int hr = S_OK; VerifyValidHandle(safeProvHandle); @@ -551,7 +549,7 @@ internal static void VerifyValidHandle(SafeHandleZeroOrMinusOneIsInvalid handle) /// Key handle /// Key property you want to get /// Returns the key property - internal static byte[] GetKeyParameter(SafeKeyHandle safeKeyHandle, int keyParam) + internal static byte[] GetKeyParameter(SafeCapiKeyHandle safeKeyHandle, ClrPropertyId keyParam) { byte[]? pb = null; int cb = 0; @@ -559,7 +557,7 @@ internal static byte[] GetKeyParameter(SafeKeyHandle safeKeyHandle, int keyParam switch (keyParam) { - case Constants.CLR_KEYLEN: + case ClrPropertyId.CLR_KEYLEN: { if (!Interop.Advapi32.CryptGetKeyParam(safeKeyHandle, Interop.Advapi32.CryptGetKeyParamFlags.KP_KEYLEN, null, ref cb, 0)) { @@ -572,13 +570,13 @@ internal static byte[] GetKeyParameter(SafeKeyHandle safeKeyHandle, int keyParam } break; } - case Constants.CLR_PUBLICKEYONLY: + case ClrPropertyId.CLR_PUBLICKEYONLY: { pb = new byte[1]; pb[0] = safeKeyHandle.PublicOnly ? (byte)1 : (byte)0; break; } - case Constants.CLR_ALGID: + case ClrPropertyId.CLR_ALGID: { // returns the algorithm ID for the key if (!Interop.Advapi32.CryptGetKeyParam(safeKeyHandle, Interop.Advapi32.CryptGetKeyParamFlags.KP_ALGID, null, ref cb, 0)) @@ -607,7 +605,7 @@ internal static byte[] GetKeyParameter(SafeKeyHandle safeKeyHandle, int keyParam /// Key handle /// Key property you want to set /// Key property value you want to set - internal static void SetKeyParameter(SafeKeyHandle safeKeyHandle, CryptGetKeyParamQueryType keyParam, byte[] value) + internal static void SetKeyParameter(SafeCapiKeyHandle safeKeyHandle, CryptGetKeyParamQueryType keyParam, byte[] value) { VerifyValidHandle(safeKeyHandle); //This will throw if handle is invalid @@ -630,7 +628,7 @@ internal static void SetKeyParameter(SafeKeyHandle safeKeyHandle, CryptGetKeyPar /// Key handle /// Key property you want to set /// Key property value you want to set - internal static void SetKeyParameter(SafeKeyHandle safeKeyHandle, CryptGetKeyParamQueryType keyParam, int value) + internal static void SetKeyParameter(SafeCapiKeyHandle safeKeyHandle, CryptGetKeyParamQueryType keyParam, int value) { VerifyValidHandle(safeKeyHandle); //This will throw if handle is invalid @@ -724,14 +722,14 @@ private static void ValidateCspFlags(CspProviderFlags flags) /// /// Helper function to get the key pair /// - internal static SafeKeyHandle GetKeyPairHelper( + internal static SafeCapiKeyHandle GetKeyPairHelper( CspAlgorithmType keyType, CspParameters parameters, int keySize, SafeProvHandle safeProvHandle) { // If the key already exists, use it, else generate a new one - SafeKeyHandle hKey; + SafeCapiKeyHandle hKey; int hr = CapiHelper.GetUserKey(safeProvHandle, parameters.KeyNumber, out hKey); if (hr != S_OK) { @@ -748,7 +746,7 @@ internal static SafeKeyHandle GetKeyPairHelper( } // check that this is indeed an RSA/DSS key. - byte[] algid = CapiHelper.GetKeyParameter(hKey, Constants.CLR_ALGID); + byte[] algid = CapiHelper.GetKeyParameter(hKey, ClrPropertyId.CLR_ALGID); int dwAlgId = BinaryPrimitives.ReadInt32LittleEndian(algid); @@ -812,7 +810,7 @@ internal static void SetPersistKeyInCsp(SafeProvHandle safeProvHandle, bool fPer // // static - internal static void DecryptKey(SafeKeyHandle safeKeyHandle, byte[] encryptedData, int encryptedDataLength, bool fOAEP, out byte[] decryptedData) + internal static void DecryptKey(SafeCapiKeyHandle safeKeyHandle, byte[] encryptedData, int encryptedDataLength, bool fOAEP, out byte[] decryptedData) { VerifyValidHandle(safeKeyHandle); Debug.Assert(encryptedData != null, "Encrypted Data is null"); @@ -872,7 +870,7 @@ internal static void DecryptKey(SafeKeyHandle safeKeyHandle, byte[] encryptedDat // The returned value in ohRetEncryptedKey is byte-reversed from the version CAPI gives us. This is for // compatibility with previous releases of the CLR and other RSA implementations. // - internal static void EncryptKey(SafeKeyHandle safeKeyHandle, byte[] pbKey, int cbKey, bool foep, [NotNull] ref byte[]? pbEncryptedKey) + internal static void EncryptKey(SafeCapiKeyHandle safeKeyHandle, byte[] pbKey, int cbKey, bool foep, [NotNull] ref byte[]? pbEncryptedKey) { VerifyValidHandle(safeKeyHandle); Debug.Assert(pbKey != null, "pbKey is null"); @@ -904,7 +902,7 @@ internal static void EncryptKey(SafeKeyHandle safeKeyHandle, byte[] pbKey, int c } internal static int EncryptData( - SafeKeyHandle hKey, + SafeCapiKeyHandle hKey, ReadOnlySpan input, Span output, bool isFinal) @@ -943,7 +941,7 @@ internal static int EncryptData( } internal static int DecryptData( - SafeKeyHandle hKey, + SafeCapiKeyHandle hKey, ReadOnlySpan input, Span output) { @@ -967,7 +965,7 @@ internal static int DecryptData( /// /// Helper for Import CSP /// - internal static void ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFlags flags, bool addNoSaltFlag, byte[] keyBlob, out SafeKeyHandle safeKeyHandle) + internal static void ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFlags flags, bool addNoSaltFlag, byte[] keyBlob, out SafeCapiKeyHandle safeKeyHandle) { // Compat note: This isn't the same check as the one done by the CLR _ImportCspBlob QCall, // but this does match the .NET Framework CLR behavior and the only scenarios it @@ -987,8 +985,8 @@ internal static void ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFla dwCapiFlags |= (int)CryptGenKeyFlags.CRYPT_NO_SALT; } - SafeKeyHandle hKey; - if (!CryptImportKey(saveProvHandle, keyBlob, SafeKeyHandle.InvalidHandle, dwCapiFlags, out hKey)) + SafeCapiKeyHandle hKey; + if (!CryptImportKey(saveProvHandle, keyBlob, SafeCapiKeyHandle.InvalidHandle, dwCapiFlags, out hKey)) { int hr = Marshal.GetHRForLastWin32Error(); @@ -1006,7 +1004,7 @@ internal static void ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFla /// /// Helper for Export CSP /// - internal static byte[] ExportKeyBlob(bool includePrivateParameters, SafeKeyHandle safeKeyHandle) + internal static byte[] ExportKeyBlob(bool includePrivateParameters, SafeCapiKeyHandle safeKeyHandle) { VerifyValidHandle(safeKeyHandle); @@ -1014,13 +1012,13 @@ internal static byte[] ExportKeyBlob(bool includePrivateParameters, SafeKeyHandl int cbRawData = 0; int dwBlobType = includePrivateParameters ? PRIVATEKEYBLOB : PUBLICKEYBLOB; - if (!Interop.Advapi32.CryptExportKey(safeKeyHandle, SafeKeyHandle.InvalidHandle, dwBlobType, 0, null, ref cbRawData)) + if (!Interop.Advapi32.CryptExportKey(safeKeyHandle, SafeCapiKeyHandle.InvalidHandle, dwBlobType, 0, null, ref cbRawData)) { throw GetErrorCode().ToCryptographicException(); } pbRawData = new byte[cbRawData]; - if (!Interop.Advapi32.CryptExportKey(safeKeyHandle, SafeKeyHandle.InvalidHandle, dwBlobType, 0, pbRawData, ref cbRawData)) + if (!Interop.Advapi32.CryptExportKey(safeKeyHandle, SafeCapiKeyHandle.InvalidHandle, dwBlobType, 0, pbRawData, ref cbRawData)) { throw GetErrorCode().ToCryptographicException(); } @@ -1119,6 +1117,17 @@ internal static HashAlgorithm ObjToHashAlgorithm(object hashAlg) => _ => throw new ArgumentException(SR.Argument_InvalidValue, nameof(hashAlg)), }; + internal static HashAlgorithmName AlgIdToHashAlgorithmName(int hashAlg) => + hashAlg switch + { + CapiHelper.CALG_MD5 => HashAlgorithmName.MD5, + CapiHelper.CALG_SHA1 => HashAlgorithmName.SHA1, + CapiHelper.CALG_SHA_256 => HashAlgorithmName.SHA256, + CapiHelper.CALG_SHA_384 => HashAlgorithmName.SHA384, + CapiHelper.CALG_SHA_512 => HashAlgorithmName.SHA512, + _ => throw new ArgumentException(SR.Argument_InvalidValue, nameof(hashAlg)), + }; + /// /// Convert an OID into a CAPI-1 CALG ID. /// @@ -1149,7 +1158,7 @@ private static int GetAlgIdFromOid(string oid, OidGroup oidGroup) /// /// Helper for RSACryptoServiceProvider.SignData/SignHash apis. /// - public static byte[] SignValue(SafeProvHandle hProv, SafeKeyHandle hKey, int keyNumber, int calgKey, int calgHash, byte[] hash) + public static byte[] SignValue(SafeProvHandle hProv, SafeCapiKeyHandle hKey, int keyNumber, int calgKey, int calgHash, byte[] hash) { using (SafeHashHandle hHash = hProv.CreateHashHandle(hash, calgHash)) { @@ -1186,7 +1195,7 @@ public static byte[] SignValue(SafeProvHandle hProv, SafeKeyHandle hKey, int key /// /// Helper for RSACryptoServiceProvider.VerifyData/VerifyHash apis. /// - public static bool VerifySign(SafeProvHandle hProv, SafeKeyHandle hKey, int calgKey, int calgHash, byte[] hash, byte[] signature) + public static bool VerifySign(SafeProvHandle hProv, SafeCapiKeyHandle hKey, int calgKey, int calgHash, byte[] hash, byte[] signature) { switch (calgKey) { @@ -1231,10 +1240,10 @@ public static void DeriveKey( VerifyValidHandle(hProv); SafeHashHandle? hHash = null; - SafeKeyHandle? hKey = null; + SafeCapiKeyHandle? hKey = null; try { - if (!CryptCreateHash(hProv, algidHash, SafeKeyHandle.InvalidHandle, Interop.Advapi32.CryptCreateHashFlags.None, out hHash)) + if (!CryptCreateHash(hProv, algidHash, SafeCapiKeyHandle.InvalidHandle, Interop.Advapi32.CryptCreateHashFlags.None, out hHash)) { int hr = Marshal.GetHRForLastWin32Error(); throw hr.ToCryptographicException(); @@ -1295,13 +1304,13 @@ public static void DeriveKey( // Helper method used by DeriveKey (above) to return the key contents. // WARNING: This function side-effects its first argument (hProv) - private static void UnloadKey(SafeProvHandle hProv, SafeKeyHandle hKey, [NotNull] ref byte[]? key_out, ref int cb_out) + private static void UnloadKey(SafeProvHandle hProv, SafeCapiKeyHandle hKey, [NotNull] ref byte[]? key_out, ref int cb_out) { - SafeKeyHandle? hPubKey = null; + SafeCapiKeyHandle? hPubKey = null; try { // Import the public key - if (!CryptImportKey(hProv, RgbPubKey, SafeKeyHandle.InvalidHandle, 0, out hPubKey)) + if (!CryptImportKey(hProv, RgbPubKey, SafeCapiKeyHandle.InvalidHandle, 0, out hPubKey)) { int hr = Marshal.GetHRForLastWin32Error(); throw hr.ToCryptographicException(); @@ -1369,7 +1378,7 @@ private static SafeHashHandle CreateHashHandle(this SafeProvHandle hProv, byte[] private static SafeHashHandle? CreateHashHandle(this SafeProvHandle hProv, byte[] hash, int calgHash, bool throwOnSizeError) { SafeHashHandle? hHash; - if (!CryptCreateHash(hProv, calgHash, SafeKeyHandle.InvalidHandle, Interop.Advapi32.CryptCreateHashFlags.None, out hHash)) + if (!CryptCreateHash(hProv, calgHash, SafeCapiKeyHandle.InvalidHandle, Interop.Advapi32.CryptCreateHashFlags.None, out hHash)) { int hr = Marshal.GetHRForLastWin32Error(); @@ -1431,7 +1440,7 @@ public static CryptographicException GetEFailException() public static bool CryptGetUserKey( SafeProvHandle safeProvHandle, int dwKeySpec, - out SafeKeyHandle safeKeyHandle) + out SafeCapiKeyHandle safeKeyHandle) { bool response = Interop.Advapi32.CryptGetUserKey(safeProvHandle, dwKeySpec, out safeKeyHandle); @@ -1444,7 +1453,7 @@ public static bool CryptGenKey( SafeProvHandle safeProvHandle, int algId, int dwFlags, - out SafeKeyHandle safeKeyHandle) + out SafeCapiKeyHandle safeKeyHandle) { bool response = Interop.Advapi32.CryptGenKey(safeProvHandle, algId, dwFlags, out safeKeyHandle); @@ -1456,9 +1465,9 @@ public static bool CryptGenKey( public static unsafe bool CryptImportKey( SafeProvHandle hProv, ReadOnlySpan pbData, - SafeKeyHandle hPubKey, + SafeCapiKeyHandle hPubKey, int dwFlags, - out SafeKeyHandle phKey) + out SafeCapiKeyHandle phKey) { fixed (byte* pbDataPtr = pbData) { @@ -1473,7 +1482,7 @@ public static unsafe bool CryptImportKey( public static bool CryptCreateHash( SafeProvHandle hProv, int algId, - SafeKeyHandle hKey, + SafeCapiKeyHandle hKey, Interop.Advapi32.CryptCreateHashFlags dwFlags, out SafeHashHandle phHash) { @@ -1489,7 +1498,7 @@ public static bool CryptDeriveKey( int algId, SafeHashHandle phHash, int dwFlags, - out SafeKeyHandle phKey) + out SafeCapiKeyHandle phKey) { bool response = Interop.Advapi32.CryptDeriveKey(hProv, algId, phHash, dwFlags, out phKey); @@ -1497,7 +1506,7 @@ public static bool CryptDeriveKey( return response; } - }//End of class CapiHelper : Wrappers + } /// /// All the Crypto flags are capture in following @@ -1549,6 +1558,7 @@ internal enum CryptGetKeyParamQueryType : int KP_KEYLEN = 9, // Length of key in bits KP_ALGID = 7 // Key algorithm } + internal enum CryptGenKeyFlags : int { // dwFlag definitions for CryptGenKey @@ -1575,5 +1585,20 @@ internal enum CspAlgorithmType Rsa = 0, Dss = 1 } - } //End CapiHelper:Flags -} //End Namespace Internal.NativeCrypto + + internal enum ClrPropertyId + { + CLR_KEYLEN = 1, + CLR_PUBLICKEYONLY = 2, + CLR_EXPORTABLE = 3, + CLR_REMOVABLE = 4, + CLR_HARDWARE = 5, + CLR_ACCESSIBLE = 6, + CLR_PROTECTED = 7, + CLR_UNIQUE_CONTAINER = 8, + CLR_ALGID = 9, + CLR_PP_CLIENT_HWND = 10, + CLR_PP_PIN = 11, + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Cng.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Cng.NotSupported.cs new file mode 100644 index 00000000000000..7495ae1d202605 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Cng.NotSupported.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; +using System.Text; +using Microsoft.Win32.SafeHandles; + +namespace Microsoft.Win32.SafeHandles +{ + public abstract partial class SafeNCryptHandle : SafeHandleZeroOrMinusOneIsInvalid + { + [SupportedOSPlatform("windows")] + protected SafeNCryptHandle() : base(default(bool)) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + protected SafeNCryptHandle(IntPtr handle, SafeHandle parentHandle) : base(default(bool)) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + protected override bool ReleaseHandle() => false; + + protected abstract bool ReleaseNativeHandle(); + } + public sealed partial class SafeNCryptKeyHandle : SafeNCryptHandle + { + [SupportedOSPlatform("windows")] + public SafeNCryptKeyHandle() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public SafeNCryptKeyHandle(IntPtr handle, SafeHandle parentHandle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + protected override bool ReleaseNativeHandle() => false; + } + public sealed partial class SafeNCryptProviderHandle : SafeNCryptHandle + { + [SupportedOSPlatform("windows")] + public SafeNCryptProviderHandle() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + protected override bool ReleaseNativeHandle() => false; + } + public sealed partial class SafeNCryptSecretHandle : SafeNCryptHandle + { + [SupportedOSPlatform("windows")] + public SafeNCryptSecretHandle() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + protected override bool ReleaseNativeHandle() => false; + } +} + +namespace System.Security.Cryptography +{ + public sealed partial class AesCng : Aes + { + [SupportedOSPlatform("windows")] + public AesCng() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public AesCng(string keyName) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public AesCng(string keyName, CngProvider provider) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public AesCng(string keyName, CngProvider provider, CngKeyOpenOptions openOptions) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + public override void GenerateKey() { } + public override void GenerateIV() { } + public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) => null!; + public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) => null!; + } + public sealed partial class CngKey : System.IDisposable + { + internal CngKey() { } + public CngAlgorithm Algorithm => null!; + public CngAlgorithmGroup? AlgorithmGroup => null; + public CngExportPolicies ExportPolicy => default; + public SafeNCryptKeyHandle Handle => null!; + public bool IsEphemeral => false; + public bool IsMachineKey => false; + public string? KeyName => null; + public int KeySize => default; + public CngKeyUsages KeyUsage => default; + public IntPtr ParentWindowHandle { get => default; set { } } + public CngProvider? Provider => null; + public SafeNCryptProviderHandle ProviderHandle => null!; + public CngUIPolicy UIPolicy => null!; + public string? UniqueName => null; + public void Delete() { } + public void Dispose() { } + public byte[] Export(CngKeyBlobFormat format) => null!; + public CngProperty GetProperty(string name, CngPropertyOptions options) => default; + public bool HasProperty(string name, CngPropertyOptions options) => false; + public void SetProperty(CngProperty property) { } + + [SupportedOSPlatform("windows")] + public static CngKey Create(CngAlgorithm algorithm) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static CngKey Create(CngAlgorithm algorithm, string? keyName) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static CngKey Create(CngAlgorithm algorithm, string? keyName, CngKeyCreationParameters? creationParameters) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static bool Exists(string keyName) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static bool Exists(string keyName, CngProvider provider) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static bool Exists(string keyName, CngProvider provider, CngKeyOpenOptions options) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static CngKey Open(SafeNCryptKeyHandle keyHandle, CngKeyHandleOpenOptions keyHandleOpenOptions) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static CngKey Open(string keyName) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static CngKey Open(string keyName, CngProvider provider) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public static CngKey Open(string keyName, CngProvider provider, CngKeyOpenOptions openOptions) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + } + public sealed partial class DSACng : DSA + { + [SupportedOSPlatform("windows")] + public DSACng() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public DSACng(int keySize) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public DSACng(CngKey key) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + public CngKey Key => null!; + public override byte[] CreateSignature(byte[] rgbHash) => null!; + public override DSAParameters ExportParameters(bool includePrivateParameters) => default; + public override void ImportParameters(DSAParameters parameters) { } + public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) => false; + } + public sealed partial class ECDiffieHellmanCng : ECDiffieHellman + { + [SupportedOSPlatform("windows")] + public ECDiffieHellmanCng() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public ECDiffieHellmanCng(int keySize) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public ECDiffieHellmanCng(CngKey key) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public ECDiffieHellmanCng(ECCurve curve) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + public CngAlgorithm HashAlgorithm { get => null!; set { } } + public byte[]? HmacKey { get => null; set { } } + public CngKey Key => null!; + public ECDiffieHellmanKeyDerivationFunction KeyDerivationFunction { get => default; set { } } + public byte[]? Label { get => null; set { } } + public byte[]? SecretAppend { get => null; set { } } + public byte[]? SecretPrepend { get => null; set { } } + public byte[]? Seed { get => null; set { } } + public bool UseSecretAgreementAsHmacKey => false; + public SafeNCryptSecretHandle DeriveSecretAgreementHandle(CngKey otherPartyPublicKey) => null!; + public SafeNCryptSecretHandle DeriveSecretAgreementHandle(ECDiffieHellmanPublicKey otherPartyPublicKey) => null!; + public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey) => null!; + public void FromXmlString(string xml, ECKeyXmlFormat format) { } + public string ToXmlString(ECKeyXmlFormat format) => null!; + public override ECDiffieHellmanPublicKey PublicKey => null!; + } + public sealed partial class ECDiffieHellmanCngPublicKey : ECDiffieHellmanPublicKey + { + internal ECDiffieHellmanCngPublicKey() { } + public CngKeyBlobFormat BlobFormat => null!; + protected override void Dispose(bool disposing) { } + public CngKey Import() => null!; + + [SupportedOSPlatform("windows")] + public static ECDiffieHellmanPublicKey FromByteArray(byte[] publicKeyBlob, CngKeyBlobFormat format) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + // Also throws in Windows, no SupportedOSPlatform required. + public static ECDiffieHellmanCngPublicKey FromXmlString(string xml) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + } + public sealed partial class ECDsaCng : ECDsa + { + [SupportedOSPlatform("windows")] + public ECDsaCng() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public ECDsaCng(int keySize) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public ECDsaCng(CngKey key) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public ECDsaCng(ECCurve curve) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + public CngAlgorithm HashAlgorithm { get => null!; set { } } + public CngKey Key => null!; + public void FromXmlString(string xml, ECKeyXmlFormat format) { } + public byte[] SignData(byte[] data) => null!; + public byte[] SignData(byte[] data, int offset, int count) => null!; + public byte[] SignData(System.IO.Stream data) => null!; + public string ToXmlString(ECKeyXmlFormat format) => null!; + public bool VerifyData(byte[] data, byte[] signature) => false; + public bool VerifyData(byte[] data, int offset, int count, byte[] signature) => false; + public bool VerifyData(System.IO.Stream data, byte[] signature) => false; + public override byte[] SignHash(byte[] hash) => null!; + public override bool VerifyHash(byte[] hash, byte[] signature) => false; + } + public sealed partial class RSACng : RSA + { + [SupportedOSPlatform("windows")] + public RSACng() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public RSACng(int keySize) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public RSACng(CngKey key) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + public CngKey Key => null!; + public override RSAParameters ExportParameters(bool includePrivateParameters) => default; + public override void ImportParameters(RSAParameters parameters) { } + } + public sealed partial class TripleDESCng : TripleDES + { + [SupportedOSPlatform("windows")] + public TripleDESCng() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public TripleDESCng(string keyName) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public TripleDESCng(string keyName, CngProvider provider) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + [SupportedOSPlatform("windows")] + public TripleDESCng(string keyName, CngProvider provider, CngKeyOpenOptions openOptions) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyCng); + } + + public override void GenerateKey() { } + public override void GenerateIV() { } + public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) => null!; + public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) => null!; + } +} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngAlgorithm.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithm.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngAlgorithm.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithm.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngAlgorithmCore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithmCore.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngAlgorithmCore.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithmCore.cs index 7273ea9b6400dc..d5bcfafaaa5029 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngAlgorithmCore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithmCore.cs @@ -1,13 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; -using System.Security.Cryptography; using Microsoft.Win32.SafeHandles; using static Interop.NCrypt; -namespace Internal.Cryptography +namespace System.Security.Cryptography { // // Common infrastructure for crypto algorithms that accept CngKeys. @@ -15,7 +13,9 @@ namespace Internal.Cryptography internal struct CngAlgorithmCore { private readonly string _disposedName; +#pragma warning disable CS0649 public CngAlgorithm? DefaultKeyType; +#pragma warning restore CS0649 private CngKey? _lazyKey; private bool _disposed; diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngAlgorithmGroup.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithmGroup.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngAlgorithmGroup.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngAlgorithmGroup.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngExportPolicies.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngExportPolicies.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngExportPolicies.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngExportPolicies.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngHelpers.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngHelpers.cs new file mode 100644 index 00000000000000..6e316bf6524545 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngHelpers.cs @@ -0,0 +1,242 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; + +using ErrorCode = Interop.NCrypt.ErrorCode; + +namespace System.Security.Cryptography +{ + internal static class CngHelpers + { + private static readonly CngKeyBlobFormat s_cipherKeyBlobFormat = new CngKeyBlobFormat(Interop.NCrypt.NCRYPT_CIPHER_KEY_BLOB); + + internal static SafeNCryptProviderHandle OpenStorageProvider(this CngProvider provider) + { + string providerName = provider.Provider; + SafeNCryptProviderHandle providerHandle; + ErrorCode errorCode = Interop.NCrypt.NCryptOpenStorageProvider(out providerHandle, providerName, 0); + + if (errorCode != ErrorCode.ERROR_SUCCESS) + { + throw errorCode.ToCryptographicException(); + } + + return providerHandle; + } + + public static void SetExportPolicy(this SafeNCryptKeyHandle keyHandle, CngExportPolicies exportPolicy) + { + unsafe + { + ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty( + keyHandle, + KeyPropertyName.ExportPolicy, + &exportPolicy, + sizeof(CngExportPolicies), + CngPropertyOptions.Persist); + + if (errorCode != ErrorCode.ERROR_SUCCESS) + { + throw errorCode.ToCryptographicException(); + } + } + } + + /// + /// Returns a CNG key property. + /// + /// + /// null - if property not defined on key. + /// throws - for any other type of error. + /// + internal static byte[]? GetProperty(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) + { + Debug.Assert(!ncryptHandle.IsInvalid); + unsafe + { + ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty( + ncryptHandle, + propertyName, + null, + 0, + out int numBytesNeeded, + options); + + if (errorCode == ErrorCode.NTE_NOT_FOUND) + { + return null; + } + + if (errorCode != ErrorCode.ERROR_SUCCESS) + { + throw errorCode.ToCryptographicException(); + } + + byte[] propertyValue = new byte[numBytesNeeded]; + + fixed (byte* pPropertyValue = propertyValue) + { + errorCode = Interop.NCrypt.NCryptGetProperty( + ncryptHandle, + propertyName, + pPropertyValue, + propertyValue.Length, + out numBytesNeeded, + options); + } + + if (errorCode == ErrorCode.NTE_NOT_FOUND) + { + return null; + } + + if (errorCode != ErrorCode.ERROR_SUCCESS) + { + throw errorCode.ToCryptographicException(); + } + + Array.Resize(ref propertyValue, numBytesNeeded); + return propertyValue; + } + } + + /// + /// Retrieve a well-known CNG string property. (Note: .NET Framework compat: this helper likes to return special + /// values rather than throw exceptions for missing or ill-formatted property values. Only use it for well-known + /// properties that are unlikely to be ill-formatted.) + /// + internal static string? GetPropertyAsString(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) + { + Debug.Assert(!ncryptHandle.IsInvalid); + byte[]? value = GetProperty(ncryptHandle, propertyName, options); + + if (value == null) + { + // .NET Framework compat: return null if key not present. + return null; + } + + if (value.Length == 0) + { + // .NET Framework compat: return empty if property value is 0-length. + return string.Empty; + } + + unsafe + { + fixed (byte* pValue = &value[0]) + { + string valueAsString = Marshal.PtrToStringUni((IntPtr)pValue)!; + return valueAsString; + } + } + } + + /// + /// Retrieve a well-known CNG dword property. (Note: .NET Framework compat: this helper likes to return special values + /// rather than throw exceptions for missing or ill-formatted property values. Only use it for well-known properties that + /// are unlikely to be ill-formatted.) + /// + public static int GetPropertyAsDword(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) + { + byte[]? value = ncryptHandle.GetProperty(propertyName, options); + + if (value == null) + { + // .NET Framework compat: return 0 if key not present. + return 0; + } + + return BitConverter.ToInt32(value, 0); + } + + /// + /// Retrieve a well-known CNG pointer property. (Note: .NET Framework compat: this helper likes to return special values + /// rather than throw exceptions for missing or ill-formatted property values. Only use it for well-known properties that + /// are unlikely to be ill-formatted.) + /// + internal static IntPtr GetPropertyAsIntPtr(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) + { + unsafe + { + IntPtr value; + + ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty( + ncryptHandle, + propertyName, + &value, + IntPtr.Size, + out _, + options); + + if (errorCode == ErrorCode.NTE_NOT_FOUND) + { + return IntPtr.Zero; + } + + if (errorCode != ErrorCode.ERROR_SUCCESS) + { + throw errorCode.ToCryptographicException(); + } + + return value; + } + } + + /// + /// Note! This can and likely will throw if the algorithm was given a hardware-based key. + /// + internal static byte[] GetSymmetricKeyDataIfExportable(this CngKey cngKey, string algorithm) + { + const int SizeOf_NCRYPT_KEY_BLOB_HEADER = + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(int); + + byte[] keyBlob = cngKey.Export(s_cipherKeyBlobFormat); + using (MemoryStream ms = new MemoryStream(keyBlob)) + { + using (BinaryReader br = new BinaryReader(ms, Encoding.Unicode)) + { + // Read NCRYPT_KEY_BLOB_HEADER + int cbSize = br.ReadInt32(); // NCRYPT_KEY_BLOB_HEADER.cbSize + if (cbSize != SizeOf_NCRYPT_KEY_BLOB_HEADER) + throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); + + int ncryptMagic = br.ReadInt32(); // NCRYPT_KEY_BLOB_HEADER.dwMagic + if (ncryptMagic != Interop.NCrypt.NCRYPT_CIPHER_KEY_BLOB_MAGIC) + throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); + + int cbAlgName = br.ReadInt32(); // NCRYPT_KEY_BLOB_HEADER.cbAlgName + + br.ReadInt32(); // NCRYPT_KEY_BLOB_HEADER.cbKey + + string algorithmName = new string(br.ReadChars((cbAlgName / 2) - 1)); + if (algorithmName != algorithm) + throw new CryptographicException(SR.Format(SR.Cryptography_CngKeyWrongAlgorithm, algorithmName, algorithm)); + + char nullTerminator = br.ReadChar(); + if (nullTerminator != 0) + throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); + + // Read BCRYPT_KEY_DATA_BLOB_HEADER + int bcryptMagic = br.ReadInt32(); // BCRYPT_KEY_DATA_BLOB_HEADER.dwMagic + if (bcryptMagic != Interop.BCrypt.BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_MAGIC) + throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); + + int dwVersion = br.ReadInt32(); // BCRYPT_KEY_DATA_BLOB_HEADER.dwVersion + if (dwVersion != Interop.BCrypt.BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_VERSION1) + throw new CryptographicException(SR.Cryptography_KeyBlobParsingError); + + int keyLength = br.ReadInt32(); // BCRYPT_KEY_DATA_BLOB_HEADER.cbKeyData + byte[] key = br.ReadBytes(keyLength); + return key; + } + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Create.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Create.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Create.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Create.cs index d56aaacb33598f..a8ee97a859d692 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Create.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Create.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.Versioning; using Internal.Cryptography; using Microsoft.Win32.SafeHandles; @@ -18,16 +19,19 @@ public sealed partial class CngKey : IDisposable // Creation factory methods // + [SupportedOSPlatform("windows")] public static CngKey Create(CngAlgorithm algorithm) { return Create(algorithm, keyName: null); } + [SupportedOSPlatform("windows")] public static CngKey Create(CngAlgorithm algorithm, string? keyName) { return Create(algorithm, keyName, creationParameters: null); } + [SupportedOSPlatform("windows")] public static CngKey Create(CngAlgorithm algorithm, string? keyName, CngKeyCreationParameters? creationParameters) { if (algorithm == null) @@ -105,7 +109,7 @@ private static void InitializeKeyProperties(SafeNCryptKeyHandle keyHandle, CngKe { byte[]? value = property.GetValueWithoutCopying(); int valueLength = (value == null) ? 0 : value.Length; - fixed (byte* pValue = value.MapZeroLengthArrayToNonNullPointer()) + fixed (byte* pValue = MapZeroLengthArrayToNonNullPointer(value)) { ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, property.Name, pValue, valueLength, property.Options); if (errorCode != ErrorCode.ERROR_SUCCESS) diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Delete.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Delete.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Delete.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Delete.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.EC.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.EC.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.EC.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.EC.cs index 32f7af604ea439..c47f427b4cf1d6 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.EC.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.EC.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography; using System.Diagnostics; -using BCRYPT_ECC_PARAMETER_HEADER = Interop.BCrypt.BCRYPT_ECC_PARAMETER_HEADER; -using Internal.NativeCrypto; namespace System.Security.Cryptography { @@ -115,14 +112,17 @@ internal static CngAlgorithm EcdhCurveNameToAlgorithm(string name) { case "nistP256": case "ECDH_P256": + case "ECDSA_P256": return CngAlgorithm.ECDiffieHellmanP256; case "nistP384": case "ECDH_P384": + case "ECDSA_P384": return CngAlgorithm.ECDiffieHellmanP384; case "nistP521": case "ECDH_P521": + case "ECDSA_P521": return CngAlgorithm.ECDiffieHellmanP521; } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Exists.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Exists.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Exists.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Exists.cs index d4124aafc272b4..ff1ba4a7c83380 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Exists.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Exists.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; using Internal.Cryptography; @@ -18,16 +19,19 @@ public sealed partial class CngKey : IDisposable // Check to see if a key already exists // + [SupportedOSPlatform("windows")] public static bool Exists(string keyName) { return Exists(keyName, provider: CngProvider.MicrosoftSoftwareKeyStorageProvider); } + [SupportedOSPlatform("windows")] public static bool Exists(string keyName, CngProvider provider) { return Exists(keyName, provider, options: CngKeyOpenOptions.None); } + [SupportedOSPlatform("windows")] public static bool Exists(string keyName, CngProvider provider, CngKeyOpenOptions options) { if (keyName == null) diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Export.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Export.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Export.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Export.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Import.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Import.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Import.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Import.cs index 6b4950fe4ce144..4a7e64000cbd92 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Import.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Import.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; using Internal.Cryptography; @@ -23,6 +24,7 @@ internal static CngKey Import(ReadOnlySpan keyBlob, CngKeyBlobFormat forma return Import(keyBlob, null, format, CngProvider.MicrosoftSoftwareKeyStorageProvider); } + [SupportedOSPlatform("windows")] public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format) { return Import(keyBlob, format, provider: CngProvider.MicrosoftSoftwareKeyStorageProvider); @@ -33,6 +35,7 @@ internal static CngKey Import(byte[] keyBlob, string? curveName, CngKeyBlobForma return Import(keyBlob, curveName, format, provider: CngProvider.MicrosoftSoftwareKeyStorageProvider); } + [SupportedOSPlatform("windows")] public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider) { return Import(keyBlob, null, format, provider); diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Open.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Open.cs similarity index 91% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Open.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Open.cs index 838a934a2b10b1..4f6344baf2a514 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Open.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Open.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; using Internal.Cryptography; @@ -18,16 +19,19 @@ public sealed partial class CngKey : IDisposable // Open factory methods // + [SupportedOSPlatform("windows")] public static CngKey Open(string keyName) { return Open(keyName, provider: CngProvider.MicrosoftSoftwareKeyStorageProvider); } + [SupportedOSPlatform("windows")] public static CngKey Open(string keyName, CngProvider provider) { return Open(keyName, provider, openOptions: CngKeyOpenOptions.None); } + [SupportedOSPlatform("windows")] public static CngKey Open(string keyName, CngProvider provider, CngKeyOpenOptions openOptions) { if (keyName == null) diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.OpenHandle.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.OpenHandle.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.OpenHandle.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.OpenHandle.cs index a5b61dc82fd907..51a70f8d9468b1 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.OpenHandle.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.OpenHandle.cs @@ -1,10 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; -using Internal.Cryptography; - namespace System.Security.Cryptography { /// @@ -15,6 +14,7 @@ public sealed partial class CngKey : IDisposable /// /// Wrap an existing key handle with a CngKey object /// + [SupportedOSPlatform("windows")] public static CngKey Open(SafeNCryptKeyHandle keyHandle, CngKeyHandleOpenOptions keyHandleOpenOptions) { if (keyHandle == null) diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Properties.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Properties.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Properties.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Properties.cs index 998690be8ea3a0..4507c0fccf48f6 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.Properties.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.Properties.cs @@ -62,7 +62,7 @@ public void SetProperty(CngProperty property) if (propertyValue == null) throw ErrorCode.NTE_INVALID_PARAMETER.ToCryptographicException(); - fixed (byte* pinnedPropertyValue = propertyValue.MapZeroLengthArrayToNonNullPointer()) + fixed (byte* pinnedPropertyValue = MapZeroLengthArrayToNonNullPointer(propertyValue)) { ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(_keyHandle, property.Name, pinnedPropertyValue, propertyValue.Length, property.Options); if (errorCode != ErrorCode.ERROR_SUCCESS) diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.StandardProperties.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.StandardProperties.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.StandardProperties.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.StandardProperties.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.cs similarity index 59% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.cs index 1b42de8ccb702d..dd78630eecf6fd 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKey.cs @@ -1,15 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; - using Microsoft.Win32.SafeHandles; -using Internal.Cryptography; - -using ErrorCode = Interop.NCrypt.ErrorCode; - namespace System.Security.Cryptography { /// @@ -17,6 +11,9 @@ namespace System.Security.Cryptography /// public sealed partial class CngKey : IDisposable { + private readonly SafeNCryptKeyHandle _keyHandle; + private readonly SafeNCryptProviderHandle _providerHandle; + private CngKey(SafeNCryptProviderHandle providerHandle, SafeNCryptKeyHandle keyHandle) { Debug.Assert(keyHandle != null && !keyHandle.IsInvalid && !keyHandle.IsClosed); @@ -39,7 +36,29 @@ public void Dispose() } } - private readonly SafeNCryptKeyHandle _keyHandle; - private readonly SafeNCryptProviderHandle _providerHandle; + // + // The C# construct + // + // fixed (byte* p = new byte[0]) + // + // sets "p" to 0 rather than a valid address. Sometimes, we actually want a non-NULL pointer instead. + // (Some CNG apis actually care whether the buffer pointer is NULL or not, even if the accompanying + // size argument is 0.) + // + // This helper enables the syntax: + // + // fixed (byte* p = new byte[0].MapZeroLengthArrayToNonNullPointer()) + // + // which always sets "p" to a non-NULL pointer for a non-null byte array. + // + private static byte[]? MapZeroLengthArrayToNonNullPointer(byte[]? src) + { + if (src != null && src.Length == 0) + { + return new byte[1]; + } + + return src; + } } } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyBlobFormat.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyBlobFormat.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyBlobFormat.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyBlobFormat.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyCreationOptions.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyCreationOptions.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyCreationOptions.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyCreationOptions.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyCreationParameters.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyCreationParameters.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyCreationParameters.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyCreationParameters.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyHandleOpenOptions.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyHandleOpenOptions.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyHandleOpenOptions.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyHandleOpenOptions.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyLite.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyLite.cs index 3670b98ffc0490..efa152cc562c72 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyLite.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyLite.cs @@ -1,10 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography; using Internal.Cryptography; using Microsoft.Win32.SafeHandles; @@ -13,19 +11,40 @@ namespace System.Security.Cryptography { - internal static class CngKeyLite + internal static class KeyPropertyName { - internal static class KeyPropertyName - { - internal const string Algorithm = "Algorithm Name"; // NCRYPT_ALGORITHM_PROPERTY - internal const string AlgorithmGroup = "Algorithm Group"; // NCRYPT_ALGORITHM_GROUP_PROPERTY - internal const string ECCCurveName = "ECCCurveName"; // NCRYPT_ECC_CURVE_NAME - internal const string ECCParameters = "ECCParameters"; // BCRYPT_ECC_PARAMETERS - internal const string ExportPolicy = "Export Policy"; // NCRYPT_EXPORT_POLICY_PROPERTY - internal const string Length = "Length"; // NCRYPT_LENGTH_PROPERTY - internal const string PublicKeyLength = "PublicKeyLength"; // NCRYPT_PUBLIC_KEY_LENGTH (Win10+) - } + internal const string Algorithm = "Algorithm Name"; // NCRYPT_ALGORITHM_PROPERTY + internal const string AlgorithmGroup = "Algorithm Group"; // NCRYPT_ALGORITHM_GROUP_PROPERTY + internal const string ChainingMode = "Chaining Mode"; // NCRYPT_CHAINING_MODE_PROPERTY + internal const string ECCCurveName = "ECCCurveName"; // NCRYPT_ECC_CURVE_NAME + internal const string ECCParameters = "ECCParameters"; // BCRYPT_ECC_PARAMETERS + internal const string ExportPolicy = "Export Policy"; // NCRYPT_EXPORT_POLICY_PROPERTY + internal const string InitializationVector = "IV"; // NCRYPT_INITIALIZATION_VECTOR + internal const string KeyType = "Key Type"; // NCRYPT_KEY_TYPE_PROPERTY + internal const string KeyUsage = "Key Usage"; // NCRYPT_KEY_USAGE_PROPERTY + internal const string Length = "Length"; // NCRYPT_LENGTH_PROPERTY + internal const string Name = "Name"; // NCRYPT_NAME_PROPERTY + internal const string ParentWindowHandle = "HWND Handle"; // NCRYPT_WINDOW_HANDLE_PROPERTY + internal const string PublicKeyLength = "PublicKeyLength"; // NCRYPT_PUBLIC_KEY_LENGTH (Win10+) + internal const string ProviderHandle = "Provider Handle"; // NCRYPT_PROVIDER_HANDLE_PROPERTY + internal const string UIPolicy = "UI Policy"; // NCRYPT_UI_POLICY_PROPERTY + internal const string UniqueName = "Unique Name"; // NCRYPT_UNIQUE_NAME_PROPERTY + internal const string UseContext = "Use Context"; // NCRYPT_USE_CONTEXT_PROPERTY + + + // + // Properties defined by the CLR + // + + /// + /// Is the key a CLR created ephemeral key, it will contain a single byte with value 1 if the + /// key was created by the CLR as an ephemeral key. + /// + internal const string ClrIsEphemeral = "CLR IsEphemeral"; + } + internal static class CngKeyLite + { private static readonly SafeNCryptProviderHandle s_microsoftSoftwareProviderHandle = OpenNCryptProvider("Microsoft Software Key Storage Provider"); // MS_KEY_STORAGE_PROVIDER @@ -569,58 +588,13 @@ private static SafeNCryptProviderHandle OpenNCryptProvider(string providerName) /// private static byte[]? GetProperty(SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) { - Debug.Assert(!ncryptHandle.IsInvalid); - unsafe - { - int numBytesNeeded; - ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty(ncryptHandle, propertyName, null, 0, out numBytesNeeded, options); - if (errorCode == ErrorCode.NTE_NOT_FOUND) - return null; - if (errorCode != ErrorCode.ERROR_SUCCESS) - throw errorCode.ToCryptographicException(); - - byte[] propertyValue = new byte[numBytesNeeded]; - fixed (byte* pPropertyValue = propertyValue) - { - errorCode = Interop.NCrypt.NCryptGetProperty(ncryptHandle, propertyName, pPropertyValue, propertyValue.Length, out numBytesNeeded, options); - } - if (errorCode == ErrorCode.NTE_NOT_FOUND) - return null; - if (errorCode != ErrorCode.ERROR_SUCCESS) - throw errorCode.ToCryptographicException(); - - Array.Resize(ref propertyValue, numBytesNeeded); - return propertyValue; - } - } - - /// - /// Retrieve a well-known CNG string property. (Note: .NET Framework compat: this helper likes to return special values rather than throw exceptions for missing - /// or ill-formatted property values. Only use it for well-known properties that are unlikely to be ill-formatted.) - /// - internal static string? GetPropertyAsString(SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options) - { - Debug.Assert(!ncryptHandle.IsInvalid); - byte[]? value = GetProperty(ncryptHandle, propertyName, options); - if (value == null) - return null; // .NET Framework compat: return null if key not present. - if (value.Length == 0) - return string.Empty; // .NET Framework compat: return empty if property value is 0-length. - - unsafe - { - fixed (byte* pValue = &value[0]) - { - string valueAsString = Marshal.PtrToStringUni((IntPtr)pValue)!; - return valueAsString; - } - } + return CngHelpers.GetProperty(ncryptHandle, propertyName, options); } internal static string? GetCurveName(SafeNCryptHandle ncryptHandle) { Debug.Assert(!ncryptHandle.IsInvalid); - return GetPropertyAsString(ncryptHandle, KeyPropertyName.ECCCurveName, CngPropertyOptions.None); + return ncryptHandle.GetPropertyAsString(KeyPropertyName.ECCCurveName, CngPropertyOptions.None); } internal static void SetCurveName(SafeNCryptHandle keyHandle, string curveName) @@ -655,97 +629,4 @@ private static void SetProperty(SafeNCryptHandle ncryptHandle, string propertyNa } } } - - // Limited version of CngExportPolicies from the Cng contract. - [Flags] - internal enum CngPropertyOptions : int - { - None = 0, - Persist = unchecked((int)0x80000000), //NCRYPT_PERSIST_FLAG (The property should be persisted.) - } - - // Limited version of CngKeyCreationOptions from the Cng contract. - [Flags] - internal enum CngKeyCreationOptions : int - { - None = 0x00000000, - } - - // Limited version of CngKeyOpenOptions from the Cng contract. - [Flags] - internal enum CngKeyOpenOptions : int - { - None = 0x00000000, - } - - // Limited version of CngExportPolicies from the Cng contract. - [Flags] - internal enum CngExportPolicies : int - { - None = 0x00000000, - AllowPlaintextExport = 0x00000002, // NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG - } -} - -// Internal, lightweight versions of the SafeNCryptHandle types which are public in CNG. -namespace Microsoft.Win32.SafeHandles -{ - internal class SafeNCryptHandle : SafeHandle - { - public SafeNCryptHandle() - : base(IntPtr.Zero, ownsHandle: true) - { - } - - protected override bool ReleaseHandle() - { - ErrorCode errorCode = Interop.NCrypt.NCryptFreeObject(handle); - bool success = (errorCode == ErrorCode.ERROR_SUCCESS); - Debug.Assert(success); - handle = IntPtr.Zero; - return success; - } - - public override bool IsInvalid - { - get { return handle == IntPtr.Zero; } - } - } - - internal class SafeNCryptKeyHandle : SafeNCryptHandle - { - } - - internal sealed class SafeNCryptProviderHandle : SafeNCryptHandle - { - } - - internal sealed class SafeNCryptSecretHandle : SafeNCryptHandle - { - } - -#pragma warning disable CA1419 // TODO https://github.com/dotnet/roslyn-analyzers/issues/5232: not intended for use with P/Invoke - - internal sealed class DuplicateSafeNCryptKeyHandle : SafeNCryptKeyHandle - { - public DuplicateSafeNCryptKeyHandle(SafeNCryptKeyHandle original) - : base() - { - bool success = false; - original.DangerousAddRef(ref success); - if (!success) - throw new CryptographicException(); // DangerousAddRef() never actually sets success to false, so no need to expend a resource string here. - SetHandle(original.DangerousGetHandle()); - _original = original; - } - - protected override bool ReleaseHandle() - { - _original.DangerousRelease(); - SetHandle(IntPtr.Zero); - return true; - } - - private readonly SafeNCryptKeyHandle _original; - } } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyOpenOptions.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyOpenOptions.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyOpenOptions.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyOpenOptions.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyUsages.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyUsages.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngKeyUsages.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngKeyUsages.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngPkcs8.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngPkcs8.cs index ad9914066278a5..7324a310746ba7 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngPkcs8.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngPkcs8.cs @@ -1,39 +1,33 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; - namespace System.Security.Cryptography { internal static partial class CngPkcs8 { internal struct Pkcs8Response { - internal SafeNCryptKeyHandle KeyHandle; + internal CngKey Key; internal string? GetAlgorithmGroup() { - return CngKeyLite.GetPropertyAsString( - KeyHandle, - CngKeyLite.KeyPropertyName.AlgorithmGroup, - CngPropertyOptions.None); + return Key.AlgorithmGroup!.AlgorithmGroup; } internal void FreeKey() { - KeyHandle.Dispose(); + Key.Dispose(); } } private static Pkcs8Response ImportPkcs8(ReadOnlySpan keyBlob) { - SafeNCryptKeyHandle handle = CngKeyLite.ImportKeyBlob( - Interop.NCrypt.NCRYPT_PKCS8_PRIVATE_KEY_BLOB, - keyBlob); + CngKey key = CngKey.Import(keyBlob, CngKeyBlobFormat.Pkcs8PrivateBlob); + key.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport; return new Pkcs8Response { - KeyHandle = handle, + Key = key, }; } @@ -41,15 +35,12 @@ private static Pkcs8Response ImportPkcs8( ReadOnlySpan keyBlob, ReadOnlySpan password) { - SafeNCryptKeyHandle handle = CngKeyLite.ImportKeyBlob( - Interop.NCrypt.NCRYPT_PKCS8_PRIVATE_KEY_BLOB, - keyBlob, - encrypted: true, - password); + CngKey key = CngKey.ImportEncryptedPkcs8(keyBlob, password); + key.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport; return new Pkcs8Response { - KeyHandle = handle, + Key = key, }; } } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngProperty.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngProperty.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngProperty.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngProperty.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngPropertyCollection.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngPropertyCollection.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngPropertyCollection.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngPropertyCollection.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngPropertyOptions.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngPropertyOptions.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngPropertyOptions.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngPropertyOptions.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngProvider.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngProvider.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngSymmetricAlgorithmCore.cs similarity index 91% rename from src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngSymmetricAlgorithmCore.cs index 401a8c1a7d645b..654a06a95e5588 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/CngSymmetricAlgorithmCore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngSymmetricAlgorithmCore.cs @@ -1,12 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; -using System.Security.Cryptography; +using Internal.Cryptography; using Internal.NativeCrypto; -namespace Internal.Cryptography +namespace System.Security.Cryptography { // // Common infrastructure for crypto symmetric algorithms that use Cng. @@ -89,13 +88,13 @@ public void SetKeySize(int keySize, ICngSymmetricAlgorithm outer) public void GenerateKey() { - byte[] key = Helpers.GenerateRandom(_outer.BaseKeySize.BitSizeToByteSize()); + byte[] key = Helpers.GenerateRandom(AsymmetricAlgorithmHelpers.BitsToBytes(_outer.BaseKeySize)); SetKey(key); } public void GenerateIV() { - byte[] iv = Helpers.GenerateRandom(_outer.BlockSize.BitSizeToByteSize()); + byte[] iv = Helpers.GenerateRandom(AsymmetricAlgorithmHelpers.BitsToBytes(_outer.BlockSize)); _outer.IV = iv; } @@ -150,13 +149,22 @@ private UniversalCryptoTransform CreateCryptoTransform(byte[] rgbKey, byte[]? rg long keySize = key.Length * (long)BitsPerByte; if (keySize > int.MaxValue || !((int)keySize).IsLegalSize(_outer.LegalKeySizes)) + { throw new ArgumentException(SR.Cryptography_InvalidKeySize, nameof(rgbKey)); + } if (_outer.IsWeakKey(key)) - throw new CryptographicException(SR.Cryptography_WeakKey); + { + throw new CryptographicException( + SR.Format( + SR.Cryptography_InvalidKey_Weak, + _outer.GetNCryptAlgorithmIdentifier())); + } - if (rgbIV != null && rgbIV.Length != _outer.BlockSize.BitSizeToByteSize()) + if (rgbIV != null && rgbIV.Length != AsymmetricAlgorithmHelpers.BitsToBytes(_outer.BlockSize)) + { throw new ArgumentException(SR.Cryptography_InvalidIVSize, nameof(rgbIV)); + } // CloneByteArray is null-preserving. So even when GetCipherIv returns null the iv variable // is correct, and detached from the input parameter. @@ -169,7 +177,7 @@ private UniversalCryptoTransform CreateCryptoTransform(byte[] rgbKey, byte[]? rg private UniversalCryptoTransform CreateEphemeralCryptoTransformCore(byte[] key, byte[]? iv, bool encrypting, PaddingMode padding, CipherMode mode, int feedbackSizeInBits) { - int blockSizeInBytes = _outer.BlockSize.BitSizeToByteSize(); + int blockSizeInBytes = AsymmetricAlgorithmHelpers.BitsToBytes(_outer.BlockSize); SafeAlgorithmHandle algorithmModeHandle = _outer.GetEphemeralModeHandle(mode, feedbackSizeInBits); BasicSymmetricCipher cipher = new BasicSymmetricCipherBCrypt( @@ -192,7 +200,7 @@ private UniversalCryptoTransform CreatePersistedCryptoTransformCore(Func ValidateFeedbackSize(mode, feedbackSizeInBits); Debug.Assert(mode == CipherMode.CFB ? feedbackSizeInBits == 8 : true); - int blockSizeInBytes = _outer.BlockSize.BitSizeToByteSize(); + int blockSizeInBytes = AsymmetricAlgorithmHelpers.BitsToBytes(_outer.BlockSize); BasicSymmetricCipher cipher = new BasicSymmetricCipherNCrypt( cngKeyFactory, mode, diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngUIPolicy.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngUIPolicy.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngUIPolicy.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngUIPolicy.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngUIProtectionLevels.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngUIProtectionLevels.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/CngUIProtectionLevels.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CngUIProtectionLevels.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoConfig.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoConfig.cs index 886bfb290731ec..e03c5e3756dc18 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoConfig.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoConfig.cs @@ -14,10 +14,7 @@ namespace System.Security.Cryptography public partial class CryptoConfig { #if !BROWSER - private const string AssemblyName_Cng = "System.Security.Cryptography.Cng"; - private const string AssemblyName_Csp = "System.Security.Cryptography.Csp"; private const string AssemblyName_Pkcs = "System.Security.Cryptography.Pkcs"; - private const string AssemblyName_X509Certificates = "System.Security.Cryptography.X509Certificates"; private const BindingFlags ConstructorDefault = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance; @@ -128,19 +125,20 @@ private static Dictionary DefaultNameHT Type SHA256DefaultType = typeof(System.Security.Cryptography.SHA256Managed); Type SHA384DefaultType = typeof(System.Security.Cryptography.SHA384Managed); Type SHA512DefaultType = typeof(System.Security.Cryptography.SHA512Managed); + Type SHA1CryptoServiceProviderType = typeof(SHA1CryptoServiceProvider); + Type MD5CryptoServiceProviderType = typeof(MD5CryptoServiceProvider); + Type RSACryptoServiceProviderType = typeof(RSACryptoServiceProvider); + Type DSACryptoServiceProviderType = typeof(DSACryptoServiceProvider); + Type DESCryptoServiceProviderType = typeof(DESCryptoServiceProvider); + Type TripleDESCryptoServiceProviderType = typeof(TripleDESCryptoServiceProvider); + Type RC2CryptoServiceProviderType = typeof(RC2CryptoServiceProvider); + Type AesCryptoServiceProviderType = typeof(AesCryptoServiceProvider); #pragma warning restore SYSLIB0021 +#pragma warning disable SYSLIB0023 // RNGCryptoServiceProvider is obsolete + Type RNGCryptoServiceProviderType = typeof(RNGCryptoServiceProvider); +#pragma warning restore SYSLIB0023 - string SHA1CryptoServiceProviderType = "System.Security.Cryptography.SHA1CryptoServiceProvider, " + AssemblyName_Csp; - string MD5CryptoServiceProviderType = "System.Security.Cryptography.MD5CryptoServiceProvider," + AssemblyName_Csp; - string RSACryptoServiceProviderType = "System.Security.Cryptography.RSACryptoServiceProvider, " + AssemblyName_Csp; - string DSACryptoServiceProviderType = "System.Security.Cryptography.DSACryptoServiceProvider, " + AssemblyName_Csp; - string DESCryptoServiceProviderType = "System.Security.Cryptography.DESCryptoServiceProvider, " + AssemblyName_Csp; - string TripleDESCryptoServiceProviderType = "System.Security.Cryptography.TripleDESCryptoServiceProvider, " + AssemblyName_Csp; - string RC2CryptoServiceProviderType = "System.Security.Cryptography.RC2CryptoServiceProvider, " + AssemblyName_Csp; - string RNGCryptoServiceProviderType = "System.Security.Cryptography.RNGCryptoServiceProvider, " + AssemblyName_Csp; - string AesCryptoServiceProviderType = "System.Security.Cryptography.AesCryptoServiceProvider, " + AssemblyName_Csp; - - string ECDsaCngType = "System.Security.Cryptography.ECDsaCng, " + AssemblyName_Cng; + Type ECDsaCngType = typeof(ECDsaCng); // Random number generator ht.Add("RandomNumberGenerator", RNGCryptoServiceProviderType); @@ -255,17 +253,17 @@ private static Dictionary DefaultNameHT ht.Add("http://www.w3.org/2001/04/xmldsig-more#hmac-sha512", HMACSHA512Type); // X509 Extensions (custom decoders) // Basic Constraints OID value - ht.Add("2.5.29.10", "System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension, " + AssemblyName_X509Certificates); - ht.Add("2.5.29.19", "System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension, " + AssemblyName_X509Certificates); + ht.Add("2.5.29.10", typeof(X509Certificates.X509BasicConstraintsExtension)); + ht.Add("2.5.29.19", typeof(X509Certificates.X509BasicConstraintsExtension)); // Subject Key Identifier OID value - ht.Add("2.5.29.14", "System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierExtension, " + AssemblyName_X509Certificates); + ht.Add("2.5.29.14", typeof(X509Certificates.X509SubjectKeyIdentifierExtension)); // Key Usage OID value - ht.Add("2.5.29.15", "System.Security.Cryptography.X509Certificates.X509KeyUsageExtension, " + AssemblyName_X509Certificates); + ht.Add("2.5.29.15", typeof(X509Certificates.X509KeyUsageExtension)); // Enhanced Key Usage OID value - ht.Add("2.5.29.37", "System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension, " + AssemblyName_X509Certificates); + ht.Add("2.5.29.37", typeof(X509Certificates.X509EnhancedKeyUsageExtension)); // X509Chain class can be overridden to use a different chain engine. - ht.Add("X509Chain", "System.Security.Cryptography.X509Certificates.X509Chain, " + AssemblyName_X509Certificates); + ht.Add("X509Chain", typeof(X509Certificates.X509Chain)); // PKCS9 attributes ht.Add("1.2.840.113549.1.9.3", "System.Security.Cryptography.Pkcs.Pkcs9ContentType, " + AssemblyName_Pkcs); diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspKeyContainerInfo.NotSupported.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Unix.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspKeyContainerInfo.NotSupported.cs diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs similarity index 89% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs index cda387503b0f2f..4e1c7c22144a6b 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspKeyContainerInfo.Windows.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.NativeCrypto; -using Microsoft.Win32.SafeHandles; using System.Runtime.Versioning; namespace System.Security.Cryptography @@ -49,7 +47,7 @@ public bool Accessible { get { - object? retVal = ReadKeyParameterSilent(Constants.CLR_ACCESSIBLE, throwOnNotFound: false); + object? retVal = ReadKeyParameterSilent(CapiHelper.ClrPropertyId.CLR_ACCESSIBLE, throwOnNotFound: false); if (retVal == null) { @@ -74,7 +72,7 @@ public bool Exportable return false; } - return (bool)ReadKeyParameterSilent(Constants.CLR_EXPORTABLE)!; + return (bool)ReadKeyParameterSilent(CapiHelper.ClrPropertyId.CLR_EXPORTABLE)!; } } @@ -85,7 +83,7 @@ public bool HardwareDevice { get { - return (bool)ReadDeviceParameterVerifyContext(Constants.CLR_HARDWARE); + return (bool)ReadDeviceParameterVerifyContext(CapiHelper.ClrPropertyId.CLR_HARDWARE); } } @@ -135,7 +133,7 @@ public bool Protected return true; } - return (bool)ReadKeyParameterSilent(Constants.CLR_PROTECTED)!; + return (bool)ReadKeyParameterSilent(CapiHelper.ClrPropertyId.CLR_PROTECTED)!; } } @@ -179,7 +177,7 @@ public bool Removable { get { - return (bool)ReadDeviceParameterVerifyContext(Constants.CLR_REMOVABLE); + return (bool)ReadDeviceParameterVerifyContext(CapiHelper.ClrPropertyId.CLR_REMOVABLE); } } @@ -190,14 +188,14 @@ public string UniqueKeyContainerName { get { - return (string)ReadKeyParameterSilent(Constants.CLR_UNIQUE_CONTAINER)!; + return (string)ReadKeyParameterSilent(CapiHelper.ClrPropertyId.CLR_UNIQUE_CONTAINER)!; } } /// /// Read a parameter from the current key using CRYPT_SILENT, to avoid any potential UI prompts. /// - private object? ReadKeyParameterSilent(int keyParam, bool throwOnNotFound = true) + private object? ReadKeyParameterSilent(CapiHelper.ClrPropertyId keyParam, bool throwOnNotFound = true) { const uint SilentFlags = (uint)Interop.Advapi32.CryptAcquireContextFlags.CRYPT_SILENT; @@ -224,7 +222,7 @@ public string UniqueKeyContainerName /// /// Read a parameter using VERIFY_CONTEXT to read from the device being targeted by _parameters /// - private object ReadDeviceParameterVerifyContext(int keyParam) + private object ReadDeviceParameterVerifyContext(CapiHelper.ClrPropertyId keyParam) { CspParameters parameters = new CspParameters(_parameters); diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspParameters.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspParameters.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspParameters.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspParameters.cs index 67cb9c55f86328..0053bb12258624 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspParameters.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspParameters.cs @@ -1,11 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; -using System.Security.Cryptography; using System.Runtime.Versioning; -using Internal.NativeCrypto; namespace System.Security.Cryptography { diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspProviderFlags.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspProviderFlags.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CspProviderFlags.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CspProviderFlags.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.NotSupported.cs new file mode 100644 index 00000000000000..64ffcfa2fc85b7 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.NotSupported.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; + +namespace System.Security.Cryptography +{ + [Obsolete(Obsoletions.DerivedCryptographicTypesMessage, DiagnosticId = Obsoletions.DerivedCryptographicTypesDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class DESCryptoServiceProvider : DES + { + [SuppressMessage("Microsoft.Security", "CA5351", Justification = "This is the implementation of DESCryptoServiceProvider")] + public DESCryptoServiceProvider() + { + throw new PlatformNotSupportedException(); + } + + public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) => default!; + public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) => default!; + public override void GenerateIV() { } + public override void GenerateKey() { } + } +} diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs index 34f2b13647a87c..59dfff8fa188ba 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Unix.cs @@ -30,10 +30,10 @@ public override int BlockSize public override ICryptoTransform CreateEncryptor() => _impl.CreateEncryptor(); public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) => - _impl.CreateEncryptor(rgbKey, Helpers.TrimLargeIV(rgbIV, BlockSize)); + _impl.CreateEncryptor(rgbKey, CapiHelper.TrimLargeIV(rgbIV, BlockSize)); public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) => - _impl.CreateDecryptor(rgbKey, Helpers.TrimLargeIV(rgbIV, BlockSize)); + _impl.CreateDecryptor(rgbKey, CapiHelper.TrimLargeIV(rgbIV, BlockSize)); protected override void Dispose(bool disposing) { diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs index 5829aa05f0355d..3dd55e352f74a1 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DESCryptoServiceProvider.Windows.cs @@ -3,7 +3,6 @@ using System.ComponentModel; using Internal.Cryptography; -using Internal.NativeCrypto; namespace System.Security.Cryptography { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSA.Create.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSA.Create.OpenSsl.cs new file mode 100644 index 00000000000000..3b4c8b052ab8a8 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSA.Create.OpenSsl.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + public partial class DSA : AsymmetricAlgorithm + { + private static DSA CreateCore() + { + return new DSAWrapper(new DSAOpenSsl()); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSA.Create.SecurityTransforms.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSA.Create.SecurityTransforms.cs new file mode 100644 index 00000000000000..3ce3230b5368dd --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSA.Create.SecurityTransforms.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + public partial class DSA : AsymmetricAlgorithm + { + private static DSA CreateCore() + { + return new DSAImplementation.DSASecurityTransforms(); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSA.Create.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSA.Create.Windows.cs new file mode 100644 index 00000000000000..fa667bb92ca333 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSA.Create.Windows.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + public partial class DSA : AsymmetricAlgorithm + { + private static DSA CreateCore() + { + return new DSAWrapper(new DSACng()); + } + } +} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/DSACng.ImportExport.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACng.ImportExport.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/DSACng.ImportExport.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACng.ImportExport.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/DSACng.Key.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACng.Key.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/DSACng.Key.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACng.Key.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACng.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACng.cs index 8ede9bb6dcf5ce..4bdd219dfb8f64 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACng.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACng.cs @@ -1,149 +1,44 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; -using System.Diagnostics; +using System.Runtime.Versioning; +using Internal.Cryptography; namespace System.Security.Cryptography { - public partial class DSA : AsymmetricAlgorithm + public sealed partial class DSACng : DSA { - private static DSA CreateCore() + private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(DSACng)); + + /// + /// Creates a new DSACng object that will use the specified key. The key's + /// must be Dsa. This constructor + /// creates a copy of the key. Hence, the caller can safely dispose of the + /// passed in key and continue using the DSACng object. + /// + /// Key to use for DSA operations + /// if is not an DSA key + /// if is null. + [SupportedOSPlatform("windows")] + public DSACng(CngKey key) { - return new DSAImplementation.DSACng(); - } - } - - internal static partial class DSAImplementation - { - public sealed partial class DSACng : DSA - { - private SafeNCryptKeyHandle? _keyHandle; - private int _lastKeySize; - private bool _disposed; - - private void ThrowIfDisposed() - { - if (_disposed) - { - throw new ObjectDisposedException(nameof(RSA)); - } - } - - private SafeNCryptKeyHandle GetDuplicatedKeyHandle() - { - ThrowIfDisposed(); - - int keySize = KeySize; - - if (_lastKeySize != keySize) - { - if (_keyHandle != null) - { - _keyHandle.Dispose(); - } - - const string BCRYPT_DSA_ALGORITHM = "DSA"; - - _keyHandle = CngKeyLite.GenerateNewExportableKey(BCRYPT_DSA_ALGORITHM, keySize); - _lastKeySize = keySize; - } - - return new DuplicateSafeNCryptKeyHandle(_keyHandle!); - } - - private byte[] ExportKeyBlob(bool includePrivateParameters) - { - // Use generic blob type for multiple version support - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_PRIVATE_KEY_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_PUBLIC_KEY_BLOB; - - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportKeyBlob(keyHandle, blobType); - } - } + if (key == null) + throw new ArgumentNullException(nameof(key)); - private byte[] ExportEncryptedPkcs8(ReadOnlySpan pkcs8Password, int kdfCount) - { - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportPkcs8KeyBlob(keyHandle, pkcs8Password, kdfCount); - } - } + if (key.AlgorithmGroup != CngAlgorithmGroup.Dsa) + throw new ArgumentException(SR.Cryptography_ArgDSARequiresDSAKey, nameof(key)); - private bool TryExportEncryptedPkcs8( - ReadOnlySpan pkcs8Password, - int kdfCount, - Span destination, - out int bytesWritten) - { - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.TryExportPkcs8KeyBlob( - keyHandle, - pkcs8Password, - kdfCount, - destination, - out bytesWritten); - } - } - - private void ImportKeyBlob(byte[] dsaBlob, bool includePrivate) - { - ThrowIfDisposed(); - - // Use generic blob type for multiple version support - string blobType = includePrivate ? - Interop.BCrypt.KeyBlobType.BCRYPT_PRIVATE_KEY_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_PUBLIC_KEY_BLOB; - - SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, dsaBlob); - SetKeyHandle(keyHandle); - } - - private void AcceptImport(CngPkcs8.Pkcs8Response response) - { - ThrowIfDisposed(); - - SafeNCryptKeyHandle keyHandle = response.KeyHandle; - SetKeyHandle(keyHandle); - } - - private void SetKeyHandle(SafeNCryptKeyHandle keyHandle) - { - Debug.Assert(!keyHandle.IsInvalid); - - _keyHandle = keyHandle; - - int newKeySize = CngKeyLite.GetKeyLength(keyHandle); - - // Our LegalKeySizes value stores the values that we encoded as being the correct - // legal key size limitations for this algorithm, as documented on MSDN. - // - // But on a new OS version we might not question if our limit is accurate, or MSDN - // could have been inaccurate to start with. - // - // Since the key is already loaded, we know that Windows thought it to be valid; - // therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance - // check. - ForceSetKeySize(newKeySize); - _lastKeySize = newKeySize; - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - _keyHandle?.Dispose(); - _keyHandle = null; - _disposed = true; - } + Key = CngAlgorithmCore.Duplicate(key); + } + protected override void Dispose(bool disposing) + { + _core.Dispose(); + } - base.Dispose(disposing); - } + private void ThrowIfDisposed() + { + _core.ThrowIfDisposed(); } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACryptoServiceProvider.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACryptoServiceProvider.NotSupported.cs new file mode 100644 index 00000000000000..6a6c3f910d8ebb --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACryptoServiceProvider.NotSupported.cs @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Cryptography; +using System.IO; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.Versioning; + +namespace System.Security.Cryptography +{ + public sealed class DSACryptoServiceProvider : DSA, ICspAsymmetricAlgorithm + { + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + public DSACryptoServiceProvider() + { + throw new PlatformNotSupportedException(); + } + + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + public DSACryptoServiceProvider(int dwKeySize) : base() + { + throw new PlatformNotSupportedException(); + } + + [SupportedOSPlatform("windows")] + public DSACryptoServiceProvider(int dwKeySize, CspParameters parameters) + { + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); + } + + [SupportedOSPlatform("windows")] + public DSACryptoServiceProvider(CspParameters parameters) + { + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "This is the implementation of DSACryptoServiceProvider")] + public override byte[] CreateSignature(byte[] rgbHash) => default!; + + [SupportedOSPlatform("windows")] + public CspKeyContainerInfo CspKeyContainerInfo + { + get { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspKeyContainerInfo))); } + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "This is the implementation of DSACryptoServiceProvider")] + public byte[] SignHash(byte[] rgbHash, string str) => default!; + + public byte[] ExportCspBlob(bool includePrivateParameters) => default!; + public override DSAParameters ExportParameters(bool includePrivateParameters) => default; + public void ImportCspBlob(byte[] keyBlob) { } + public override void ImportParameters(DSAParameters parameters) { } + public bool PersistKeyInCsp { get; set; } + public bool PublicOnly => default; + public byte[] SignData(byte[] buffer) => default!; + public byte[] SignData(byte[] buffer, int offset, int count) => default!; + public byte[] SignData(Stream inputStream) => default!; + public bool VerifyData(byte[] rgbData, byte[] rgbSignature) => default; + public bool VerifyHash(byte[] rgbHash, string str, byte[] rgbSignature) => default; + public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) => default; + + // UseMachineKeyStore has no effect in non-Windows + public static bool UseMachineKeyStore { get; set; } + } +} diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs index 8790cc96a79b6e..252f93272e783f 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACryptoServiceProvider.Unix.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography; -using Internal.NativeCrypto; using System.IO; using System.Diagnostics; using System.Runtime.Versioning; @@ -37,11 +36,15 @@ public sealed class DSACryptoServiceProvider : DSA, ICspAsymmetricAlgorithm ? s_legalKeySizesAndroid : s_legalKeySizesWindowsCsp; + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public DSACryptoServiceProvider() : this(DefaultKeySize) { } + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public DSACryptoServiceProvider(int dwKeySize) : base() { if (dwKeySize < 0) diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs index 186f9c80100c5f..99525802e1ebd6 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.IO; using System.Runtime.Versioning; -using Internal.NativeCrypto; namespace System.Security.Cryptography { @@ -14,15 +13,16 @@ public sealed class DSACryptoServiceProvider : DSA, ICspAsymmetricAlgorithm private int _keySize; private readonly CspParameters _parameters; private readonly bool _randomKeyContainer; - private SafeKeyHandle? _safeKeyHandle; + private SafeCapiKeyHandle? _safeKeyHandle; private SafeProvHandle? _safeProvHandle; - private readonly SHA1 _sha1; private static volatile CspProviderFlags s_useMachineKeyStore; private bool _disposed; /// /// Initializes a new instance of the DSACryptoServiceProvider class. /// + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public DSACryptoServiceProvider() : this( new CspParameters(CapiHelper.DefaultDssProviderType, @@ -36,6 +36,8 @@ public DSACryptoServiceProvider() /// Initializes a new instance of the DSACryptoServiceProvider class with the specified key size. /// /// The size of the key for the asymmetric algorithm in bits. + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] public DSACryptoServiceProvider(int dwKeySize) : this(dwKeySize, new CspParameters(CapiHelper.DefaultDssProviderType, @@ -76,14 +78,13 @@ public DSACryptoServiceProvider(int dwKeySize, CspParameters? parameters) out _randomKeyContainer); _keySize = dwKeySize; - _sha1 = SHA1.Create(); // If this is not a random container we generate, create it eagerly // in the constructor so we can report any errors now. if (!_randomKeyContainer) { // Force-read the SafeKeyHandle property, which will summon it into existence. - SafeKeyHandle localHandle = SafeKeyHandle; + SafeCapiKeyHandle localHandle = SafeKeyHandle; Debug.Assert(localHandle != null); } } @@ -126,7 +127,7 @@ private SafeProvHandle SafeProvHandle if (current != null) { - SafeKeyHandle? keyHandle = _safeKeyHandle; + SafeCapiKeyHandle? keyHandle = _safeKeyHandle; _safeKeyHandle = null; keyHandle?.Dispose(); current.Dispose(); @@ -137,7 +138,7 @@ private SafeProvHandle SafeProvHandle } } - private SafeKeyHandle SafeKeyHandle + private SafeCapiKeyHandle SafeKeyHandle { get { @@ -147,7 +148,7 @@ private SafeKeyHandle SafeKeyHandle { if (_safeKeyHandle == null) { - SafeKeyHandle hKey = CapiHelper.GetKeyPairHelper( + SafeCapiKeyHandle hKey = CapiHelper.GetKeyPairHelper( CapiHelper.CspAlgorithmType.Dss, _parameters, _keySize, @@ -169,7 +170,7 @@ private SafeKeyHandle SafeKeyHandle { lock (_parameters) { - SafeKeyHandle? current = _safeKeyHandle; + SafeCapiKeyHandle? current = _safeKeyHandle; if (ReferenceEquals(value, current)) { @@ -192,7 +193,7 @@ public CspKeyContainerInfo CspKeyContainerInfo { // .NET Framework compat: Read the SafeKeyHandle property to force the key to load, // because it might throw here. - SafeKeyHandle localHandle = SafeKeyHandle; + SafeCapiKeyHandle localHandle = SafeKeyHandle; Debug.Assert(localHandle != null); return new CspKeyContainerInfo(_parameters, _randomKeyContainer); @@ -203,7 +204,7 @@ public override int KeySize { get { - byte[] keySize = CapiHelper.GetKeyParameter(SafeKeyHandle, Constants.CLR_KEYLEN); + byte[] keySize = CapiHelper.GetKeyParameter(SafeKeyHandle, CapiHelper.ClrPropertyId.CLR_KEYLEN); _keySize = BinaryPrimitives.ReadInt32LittleEndian(keySize); return _keySize; } @@ -246,7 +247,7 @@ public bool PublicOnly { get { - byte[] publicKey = CapiHelper.GetKeyParameter(SafeKeyHandle, Constants.CLR_PUBLICKEYONLY); + byte[] publicKey = CapiHelper.GetKeyParameter(SafeKeyHandle, CapiHelper.ClrPropertyId.CLR_PUBLICKEYONLY); return (publicKey[0] == 1); } } @@ -336,7 +337,7 @@ public void ImportCspBlob(byte[] keyBlob) { ThrowIfDisposed(); - SafeKeyHandle safeKeyHandle; + SafeCapiKeyHandle safeKeyHandle; if (IsPublic(keyBlob)) { @@ -386,7 +387,7 @@ public override void ImportEncryptedPkcs8PrivateKey( /// The DSA signature for the specified data. public byte[] SignData(Stream inputStream) { - byte[] hashVal = _sha1.ComputeHash(inputStream); + byte[] hashVal = SHA1.HashData(inputStream); return SignHash(hashVal, null); } @@ -397,7 +398,7 @@ public byte[] SignData(Stream inputStream) /// The DSA signature for the specified data. public byte[] SignData(byte[] buffer) { - byte[] hashVal = _sha1.ComputeHash(buffer); + byte[] hashVal = SHA1.HashData(buffer); return SignHash(hashVal, null); } @@ -410,7 +411,7 @@ public byte[] SignData(byte[] buffer) /// The DSA signature for the specified data. public byte[] SignData(byte[] buffer, int offset, int count) { - byte[] hashVal = _sha1.ComputeHash(buffer, offset, count); + byte[] hashVal = SHA1.HashData(new ReadOnlySpan(buffer, offset, count)); return SignHash(hashVal, null); } @@ -422,7 +423,7 @@ public byte[] SignData(byte[] buffer, int offset, int count) /// true if the signature verifies as valid; otherwise, false. public bool VerifyData(byte[] rgbData, byte[] rgbSignature) { - byte[] hashVal = _sha1.ComputeHash(rgbData); + byte[] hashVal = SHA1.HashData(rgbData); return VerifyHash(hashVal, null, rgbSignature); } @@ -454,7 +455,7 @@ protected override byte[] HashData(byte[] data, int offset, int count, HashAlgor throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name); } - return _sha1.ComputeHash(data, offset, count); + return SHA1.HashData(new ReadOnlySpan(data, offset, count)); } protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) @@ -468,7 +469,7 @@ protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name); } - return _sha1.ComputeHash(data); + return SHA1.HashData(data); } /// @@ -486,8 +487,8 @@ public byte[] SignHash(byte[] rgbHash, string? str) int calgHash = CapiHelper.NameOrOidToHashAlgId(str, OidGroup.HashAlgorithm); - if (rgbHash.Length != _sha1.HashSize / 8) - throw new CryptographicException(SR.Format(SR.Cryptography_InvalidHashSize, "SHA1", _sha1.HashSize / 8)); + if (rgbHash.Length != SHA1.HashSizeInBytes) + throw new CryptographicException(SR.Format(SR.Cryptography_InvalidHashSize, "SHA1", SHA1.HashSizeInBytes)); return CapiHelper.SignValue( SafeProvHandle, diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/DSAOpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAOpenSsl.cs similarity index 86% rename from src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/DSAOpenSsl.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAOpenSsl.cs index 3a2adb68ebb6e6..6847a0a1f56a75 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/DSAOpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAOpenSsl.cs @@ -1,12 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { public sealed partial class DSAOpenSsl : DSA { + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public DSAOpenSsl(DSAParameters parameters) { ThrowIfNotSupported(); @@ -25,6 +31,11 @@ public DSAOpenSsl(DSAParameters parameters) /// /// /// is not a valid enveloped DSA* + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public DSAOpenSsl(SafeEvpPKeyHandle pkeyHandle) { if (pkeyHandle == null) @@ -54,6 +65,11 @@ public DSAOpenSsl(SafeEvpPKeyHandle pkeyHandle) /// /// A pointer to an OpenSSL DSA* /// is invalid + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public DSAOpenSsl(IntPtr handle) { if (handle == IntPtr.Zero) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAWrapper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAWrapper.cs new file mode 100644 index 00000000000000..904ed56bfb6b8e --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/DSAWrapper.cs @@ -0,0 +1,165 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.IO; +using Internal.Cryptography; + +namespace System.Security.Cryptography +{ + internal sealed class DSAWrapper : DSA + { + private readonly DSA _wrapped; + + internal DSAWrapper(DSA wrapped) + { + Debug.Assert(wrapped != null); + _wrapped = wrapped; + } + + public override DSAParameters ExportParameters(bool includePrivateParameters) => + _wrapped.ExportParameters(includePrivateParameters); + + public override void ImportParameters(DSAParameters parameters) => + _wrapped.ImportParameters(parameters); + + public override byte[] CreateSignature(byte[] rgbHash) => + _wrapped.CreateSignature(rgbHash); + + public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) => + _wrapped.VerifySignature(rgbHash, rgbSignature); + + public override byte[] SignData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => + _wrapped.SignData(data, offset, count, hashAlgorithm); + + public override byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm) => + _wrapped.SignData(data, hashAlgorithm); + + public override bool VerifyData( + byte[] data, + int offset, + int count, + byte[] signature, + HashAlgorithmName hashAlgorithm) => + _wrapped.VerifyData(data, offset, count, signature, hashAlgorithm); + + public override bool VerifyData(Stream data, byte[] signature, HashAlgorithmName hashAlgorithm) => + _wrapped.VerifyData(data, signature, hashAlgorithm); + + public override bool TryCreateSignature(ReadOnlySpan hash, Span destination, out int bytesWritten) => + _wrapped.TryCreateSignature(hash, destination, out bytesWritten); + + public override bool TrySignData( + ReadOnlySpan data, + Span destination, + HashAlgorithmName hashAlgorithm, + out int bytesWritten) => + _wrapped.TrySignData(data, destination, hashAlgorithm, out bytesWritten); + + public override bool VerifyData( + ReadOnlySpan data, + ReadOnlySpan signature, + HashAlgorithmName hashAlgorithm) => + _wrapped.VerifyData(data, signature, hashAlgorithm); + + public override bool VerifySignature(ReadOnlySpan hash, ReadOnlySpan signature) => + _wrapped.VerifySignature(hash, signature); + + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) => + _wrapped.TryExportEncryptedPkcs8PrivateKey(passwordBytes, pbeParameters, destination, out bytesWritten); + + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) => + _wrapped.TryExportEncryptedPkcs8PrivateKey(password, pbeParameters, destination, out bytesWritten); + + public override bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritten) => + _wrapped.TryExportPkcs8PrivateKey(destination, out bytesWritten); + + public override bool TryExportSubjectPublicKeyInfo(Span destination, out int bytesWritten) => + _wrapped.TryExportSubjectPublicKeyInfo(destination, out bytesWritten); + + public override unsafe void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + + public override unsafe void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + + public override unsafe void ImportPkcs8PrivateKey(ReadOnlySpan source, out int bytesRead) => + _wrapped.ImportPkcs8PrivateKey(source, out bytesRead); + + public override void ImportSubjectPublicKeyInfo(ReadOnlySpan source, out int bytesRead) => + _wrapped.ImportSubjectPublicKeyInfo(source, out bytesRead); + + public override void ImportFromPem(ReadOnlySpan input) => _wrapped.ImportFromPem(input); + + public override void ImportFromEncryptedPem(ReadOnlySpan input, ReadOnlySpan password) => + _wrapped.ImportFromEncryptedPem(input, password); + + public override void ImportFromEncryptedPem(ReadOnlySpan input, ReadOnlySpan passwordBytes) => + _wrapped.ImportFromEncryptedPem(input, passwordBytes); + + public override void FromXmlString(string xmlString) => _wrapped.FromXmlString(xmlString); + + public override string ToXmlString(bool includePrivateParameters) => + _wrapped.ToXmlString(includePrivateParameters); + + public override int KeySize + { + get => _wrapped.KeySize; + set => _wrapped.KeySize = value; + } + + public override KeySizes[] LegalKeySizes => _wrapped.LegalKeySizes; + + public override string? SignatureAlgorithm => _wrapped.SignatureAlgorithm; + + public override string? KeyExchangeAlgorithm => _wrapped.KeyExchangeAlgorithm; + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _wrapped.Dispose(); + } + } + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters) => + _wrapped.ExportEncryptedPkcs8PrivateKey(passwordBytes, pbeParameters); + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters) => + _wrapped.ExportEncryptedPkcs8PrivateKey(password, pbeParameters); + + public override byte[] ExportPkcs8PrivateKey() => _wrapped.ExportPkcs8PrivateKey(); + + public override byte[] ExportSubjectPublicKeyInfo() => _wrapped.ExportSubjectPublicKeyInfo(); + + public override bool Equals(object? obj) => _wrapped.Equals(obj); + + public override int GetHashCode() => _wrapped.GetHashCode(); + + public override string ToString() => _wrapped.ToString()!; + + protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => + AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm); + + protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => + AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm); + } +} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECCng.ImportExport.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECCng.ImportExport.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECCng.ImportExport.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECCng.ImportExport.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECCngKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECCngKey.cs index 9da73eeb398a39..dc4c3c812399cf 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECCngKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECCngKey.cs @@ -53,7 +53,7 @@ internal SafeNCryptKeyHandle GetDuplicatedKeyHandle(int callerKeySizeProperty) if (ECCng.IsECNamedCurve(_lastAlgorithm)) { // Curve was previously created, so use that - return new DuplicateSafeNCryptKeyHandle(_keyHandle!); + return _keyHandle!.Duplicate(); } else { @@ -97,7 +97,7 @@ internal SafeNCryptKeyHandle GetDuplicatedKeyHandle(int callerKeySizeProperty) KeySize = callerKeySizeProperty; } - return new DuplicateSafeNCryptKeyHandle(_keyHandle!); + return _keyHandle!.Duplicate(); } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellman.Create.Cng.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellman.Create.Cng.cs index d8d4782ef63fb0..48eb815bd5ee97 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellman.Create.Cng.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellman.Create.Cng.cs @@ -7,22 +7,22 @@ public abstract partial class ECDiffieHellman : ECAlgorithm { public static new partial ECDiffieHellman Create() { - return new ECDiffieHellmanImplementation.ECDiffieHellmanCng(); + return new ECDiffieHellmanWrapper(new ECDiffieHellmanCng()); } public static partial ECDiffieHellman Create(ECCurve curve) { - return new ECDiffieHellmanImplementation.ECDiffieHellmanCng(curve); + return new ECDiffieHellmanWrapper(new ECDiffieHellmanCng(curve)); } public static partial ECDiffieHellman Create(ECParameters parameters) { - ECDiffieHellman ecdh = new ECDiffieHellmanImplementation.ECDiffieHellmanCng(); + ECDiffieHellman ecdh = new ECDiffieHellmanCng(); try { ecdh.ImportParameters(parameters); - return ecdh; + return new ECDiffieHellmanWrapper(ecdh); } catch { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellman.Create.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellman.Create.OpenSsl.cs index 1fa4161fa7f138..da2747f534277a 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellman.Create.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellman.Create.OpenSsl.cs @@ -7,22 +7,22 @@ public abstract partial class ECDiffieHellman : ECAlgorithm { public static new partial ECDiffieHellman Create() { - return new ECDiffieHellmanImplementation.ECDiffieHellmanOpenSsl(); + return new ECDiffieHellmanWrapper(new ECDiffieHellmanOpenSsl()); } public static partial ECDiffieHellman Create(ECCurve curve) { - return new ECDiffieHellmanImplementation.ECDiffieHellmanOpenSsl(curve); + return new ECDiffieHellmanWrapper(new ECDiffieHellmanOpenSsl(curve)); } public static partial ECDiffieHellman Create(ECParameters parameters) { - ECDiffieHellman ecdh = new ECDiffieHellmanImplementation.ECDiffieHellmanOpenSsl(); + ECDiffieHellman ecdh = new ECDiffieHellmanOpenSsl(); try { ecdh.ImportParameters(parameters); - return ecdh; + return new ECDiffieHellmanWrapper(ecdh); } catch { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Derive.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Derive.cs index d3e2c527169c39..deca9cfd932eeb 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Derive.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Derive.cs @@ -1,71 +1,146 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.NativeCrypto; +using System.Diagnostics; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { - internal static partial class ECDiffieHellmanImplementation + public sealed partial class ECDiffieHellmanCng : ECDiffieHellman { - public sealed partial class ECDiffieHellmanCng : ECDiffieHellman + public override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey) { - // For the public ECDiffieHellmanCng this is exposed as the HashAlgorithm property - // which is a CngAlgorithm type. We're not doing that, but we do need the default value - // for DeriveKeyMaterial. - public override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey) + if (otherPartyPublicKey == null) + throw new ArgumentNullException(nameof(otherPartyPublicKey)); + + if (otherPartyPublicKey is ECDiffieHellmanCngPublicKey otherKey) { - if (otherPartyPublicKey == null) + using (CngKey import = otherKey.Import()) { - throw new ArgumentNullException(nameof(otherPartyPublicKey)); + return DeriveKeyMaterial(import); } + } - // ECDiffieHellmanCng on .NET Framework will throw an ArgumentException in this method - // if otherPartyPublicKey is not an ECDiffieHellmanCngPublicKey. All of the other methods - // will use Import/Export to coerce the correct type for interop. + // This deviates from the .NET Framework behavior. .NET Framework can't handle unknown public + // key types, but on .NET Core there are automatically two: the public class produced by + // this class' PublicKey member, and the private class produced by ECDiffieHellman.Create().PublicKey + // + // So let's just work. + ECParameters otherPartyParameters = otherPartyPublicKey.ExportParameters(); - // None of the other Core types will match that behavior, so the ECDiffieHellman.Create() on - // Windows on .NET Core won't, either. + using (ECDiffieHellmanCng otherPartyCng = new ECDiffieHellmanCng()) + { + otherPartyCng.ImportParameters(otherPartyParameters); - // The default behavior for ECDiffieHellmanCng / ECDiffieHellman.Create() on .NET Framework was - // to derive from hash, no prepend, no append, SHA-2-256. - return DeriveKeyFromHash(otherPartyPublicKey, HashAlgorithmName.SHA256); + using (otherKey = (ECDiffieHellmanCngPublicKey)otherPartyCng.PublicKey) + using (CngKey importedKey = otherKey.Import()) + { + return DeriveKeyMaterial(importedKey); + } } + } + + public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey) + { + if (otherPartyPublicKey == null) + throw new ArgumentNullException(nameof(otherPartyPublicKey)); + if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) + throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(otherPartyPublicKey)); + if (otherPartyPublicKey.KeySize != KeySize) + throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey)); + + // Setting the flag to UseSecretAsHmacKey even when the KDF isn't HMAC, because that's what .NET Framework does. + Interop.NCrypt.SecretAgreementFlags flags = + UseSecretAgreementAsHmacKey + ? Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey + : Interop.NCrypt.SecretAgreementFlags.None; - private SafeNCryptSecretHandle DeriveSecretAgreementHandle(ECDiffieHellmanPublicKey otherPartyPublicKey) + using (SafeNCryptSecretHandle handle = DeriveSecretAgreementHandle(otherPartyPublicKey)) { - if (otherPartyPublicKey == null) + switch (KeyDerivationFunction) { - throw new ArgumentNullException(nameof(otherPartyPublicKey)); + case ECDiffieHellmanKeyDerivationFunction.Hash: + return Interop.NCrypt.DeriveKeyMaterialHash( + handle, + HashAlgorithm.Algorithm, + _secretPrepend, + _secretAppend, + flags); + case ECDiffieHellmanKeyDerivationFunction.Hmac: + return Interop.NCrypt.DeriveKeyMaterialHmac( + handle, + HashAlgorithm.Algorithm, + _hmacKey, + _secretPrepend, + _secretAppend, + flags); + case ECDiffieHellmanKeyDerivationFunction.Tls: + if (_label == null || _seed == null) + { + throw new InvalidOperationException(SR.Cryptography_TlsRequiresLabelAndSeed); + } + + return Interop.NCrypt.DeriveKeyMaterialTls( + handle, + _label, + _seed, + flags); + default: + Debug.Fail($"Unknown KDF ({KeyDerivationFunction})"); + // Match .NET Framework behavior + goto case ECDiffieHellmanKeyDerivationFunction.Tls; } + } + } - ECParameters otherPartyParameters = otherPartyPublicKey.ExportParameters(); + /// + /// Get a handle to the secret agreement generated between two parties + /// + public SafeNCryptSecretHandle DeriveSecretAgreementHandle(ECDiffieHellmanPublicKey otherPartyPublicKey) + { + if (otherPartyPublicKey == null) + throw new ArgumentNullException(nameof(otherPartyPublicKey)); - using (ECDiffieHellmanCng otherPartyCng = (ECDiffieHellmanCng)Create(otherPartyParameters)) - using (SafeNCryptKeyHandle otherPartyHandle = otherPartyCng.GetDuplicatedKeyHandle()) + if (otherPartyPublicKey is ECDiffieHellmanCngPublicKey otherKey) + { + using (CngKey importedKey = otherKey.Import()) { - string? importedKeyAlgorithmGroup = - CngKeyLite.GetPropertyAsString( - otherPartyHandle, - CngKeyLite.KeyPropertyName.AlgorithmGroup, - CngPropertyOptions.None); - - if (importedKeyAlgorithmGroup != BCryptNative.AlgorithmName.ECDH) - { - throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(otherPartyPublicKey)); - } - - if (CngKeyLite.GetKeyLength(otherPartyHandle) != KeySize) - { - throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey)); - } - - using (SafeNCryptKeyHandle localHandle = GetDuplicatedKeyHandle()) - { - return Interop.NCrypt.DeriveSecretAgreement(localHandle, otherPartyHandle); - } + return DeriveSecretAgreementHandle(importedKey); } } + + ECParameters otherPartyParameters = otherPartyPublicKey.ExportParameters(); + + using (ECDiffieHellmanCng otherPartyCng = new ECDiffieHellmanCng()) + { + otherPartyCng.ImportParameters(otherPartyParameters); + + using (otherKey = (ECDiffieHellmanCngPublicKey)otherPartyCng.PublicKey) + using (CngKey importedKey = otherKey.Import()) + { + return DeriveSecretAgreementHandle(importedKey); + } + } + } + + /// + /// Get a handle to the secret agreement between two parties + /// + public SafeNCryptSecretHandle DeriveSecretAgreementHandle(CngKey otherPartyPublicKey) + { + if (otherPartyPublicKey == null) + throw new ArgumentNullException(nameof(otherPartyPublicKey)); + if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) + throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(otherPartyPublicKey)); + if (otherPartyPublicKey.KeySize != KeySize) + throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey)); + + // This looks strange, but the Handle property returns a duplicate so we need to dispose of it when we're done + using (SafeNCryptKeyHandle localHandle = Key.Handle) + using (SafeNCryptKeyHandle otherPartyHandle = otherPartyPublicKey.Handle) + { + return Interop.NCrypt.DeriveSecretAgreement(localHandle, otherPartyHandle); + } } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Key.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Key.cs index 5ccb8f4468213b..baf5046f242e37 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Key.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Key.cs @@ -1,45 +1,135 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.NativeCrypto; +using System.Diagnostics; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { - internal static partial class ECDiffieHellmanImplementation + public sealed partial class ECDiffieHellmanCng : ECDiffieHellman { - public sealed partial class ECDiffieHellmanCng : ECDiffieHellman + /// + /// Public key used to generate key material with the second party + /// + public override ECDiffieHellmanPublicKey PublicKey { - private readonly ECCngKey _key = new ECCngKey(BCryptNative.AlgorithmName.ECDH, nameof(ECDiffieHellman)); - - private string? GetCurveName(out string? oidValue) => _key.GetCurveName(KeySize, out oidValue); + get + { + return ECDiffieHellmanCngPublicKey.FromKey(Key); + } + } - public override void GenerateKey(ECCurve curve) + /// + /// Gets the key that will be used by the ECDH object for any cryptographic operation that it uses. + /// This key object will be disposed if the key is reset, for instance by changing the KeySize + /// property, using ImportParamers to create a new key, or by Disposing of the parent ECDH object. + /// Therefore, you should make sure that the key object is no longer used in these scenarios. This + /// object will not be the same object as the CngKey passed to the ECDHCng constructor if that + /// constructor was used, however it will point at the same CNG key. + /// + public CngKey Key + { + get { - _key.GenerateKey(curve); - ForceSetKeySize(_key.KeySize); + return GetKey(); } - private SafeNCryptKeyHandle GetDuplicatedKeyHandle() => _key.GetDuplicatedKeyHandle(KeySize); + private set + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + if (value.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) + throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(value)); - private void DisposeKey() => _key.DisposeKey(); + _core.SetKey(value); - /// - /// Public key used to generate key material with the second party - /// - public override ECDiffieHellmanPublicKey PublicKey + // LegalKeySizes stores the values for either the current named curve or for the three + // curves that use size instead of name + ForceSetKeySize(value.KeySize); + } + } + + public override void GenerateKey(ECCurve curve) + { + curve.Validate(); + _core.DisposeKey(); + + if (curve.IsNamed) { - get + if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value)); + + // Map curve name to algorithm to support pre-Win10 curves + CngAlgorithm alg = CngKey.EcdhCurveNameToAlgorithm(curve.Oid.FriendlyName); + if (CngKey.IsECNamedCurve(alg.Algorithm)) { - string? curveName = GetCurveName(out _); + CngKey key = _core.GetOrGenerateKey(curve); + ForceSetKeySize(key.KeySize); + } + else + { + int keySize; + // Get the proper KeySize from algorithm name + if (alg == CngAlgorithm.ECDiffieHellmanP256) + keySize = 256; + else if (alg == CngAlgorithm.ECDiffieHellmanP384) + keySize = 384; + else if (alg == CngAlgorithm.ECDiffieHellmanP521) + keySize = 521; + else + { + Debug.Fail($"Unknown algorithm {alg}"); + throw new ArgumentException(SR.Cryptography_InvalidKeySize); + } + _core.GetOrGenerateKey(keySize, alg); + ForceSetKeySize(keySize); + } + } + else if (curve.IsExplicit) + { + CngKey key = _core.GetOrGenerateKey(curve); + ForceSetKeySize(key.KeySize); + } + else + { + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); + } + } + + private CngKey GetKey() + { + CngKey key; - return new ECDiffieHellmanCngPublicKey( - curveName == null - ? ExportFullKeyBlob(includePrivateParameters: false) - : ExportKeyBlob(includePrivateParameters: false), - curveName); + if (_core.IsKeyGeneratedNamedCurve()) + { + // Curve was previously created, so use that + key = _core.GetOrGenerateKey(null); + } + else + { + CngAlgorithm algorithm; + + // Map the current key size to a CNG algorithm name + int keySize = KeySize; + switch (keySize) + { + case 256: + algorithm = CngAlgorithm.ECDiffieHellmanP256; + break; + case 384: + algorithm = CngAlgorithm.ECDiffieHellmanP384; + break; + case 521: + algorithm = CngAlgorithm.ECDiffieHellmanP521; + break; + default: + Debug.Fail("Should not have invalid key size"); + throw new ArgumentException(SR.Cryptography_InvalidKeySize); } + key = _core.GetOrGenerateKey(keySize, algorithm); } + + return key; } } } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.Xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECDiffieHellmanCng.Xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.Xml.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.cs index be34cc620bd828..f4a574a67dcc38 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCng.cs @@ -1,121 +1,200 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; -using Microsoft.Win32.SafeHandles; -using static Internal.NativeCrypto.BCryptNative; +using System.Runtime.Versioning; namespace System.Security.Cryptography { - internal static partial class ECDiffieHellmanImplementation + /// + /// Wrapper for CNG's implementation of elliptic curve Diffie-Hellman key exchange + /// + public sealed partial class ECDiffieHellmanCng : ECDiffieHellman { - public sealed partial class ECDiffieHellmanCng : ECDiffieHellman + private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(ECDiffieHellmanCng)) { DefaultKeyType = CngAlgorithm.ECDiffieHellman }; + private CngAlgorithm _hashAlgorithm = CngAlgorithm.Sha256; + private ECDiffieHellmanKeyDerivationFunction _kdf = ECDiffieHellmanKeyDerivationFunction.Hash; + private byte[]? _hmacKey; + private byte[]? _label; + private byte[]? _secretAppend; + private byte[]? _secretPrepend; + private byte[]? _seed; + + [SupportedOSPlatform("windows")] + public ECDiffieHellmanCng(CngKey key) { - protected override void Dispose(bool disposing) + if (key == null) + throw new ArgumentNullException(nameof(key)); + + if (key.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) + throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(key)); + + Key = CngAlgorithmCore.Duplicate(key); + } + + /// + /// Hash algorithm used with the Hash and HMAC KDFs + /// + public CngAlgorithm HashAlgorithm + { + get { - if (disposing) + return _hashAlgorithm; + } + + set + { + if (_hashAlgorithm == null) { - _key.FullDispose(); + throw new ArgumentNullException(nameof(value)); } - base.Dispose(disposing); + _hashAlgorithm = value; } + } - private void ThrowIfDisposed() + /// + /// KDF used to transform the secret agreement into key material + /// + public ECDiffieHellmanKeyDerivationFunction KeyDerivationFunction + { + get { - _key.ThrowIfDisposed(); + return _kdf; } - private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters) + set { - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPRIVATE_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPUBLIC_BLOB; + if (value < ECDiffieHellmanKeyDerivationFunction.Hash || value > ECDiffieHellmanKeyDerivationFunction.Tls) + { + throw new ArgumentOutOfRangeException(nameof(value)); + } - SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecfullKeyBlob); + _kdf = value; + } + } - Debug.Assert(!keyHandle.IsInvalid); + /// + /// Key used with the HMAC KDF + /// + public byte[]? HmacKey + { + get { return _hmacKey; } + set { _hmacKey = value; } + } - _key.SetHandle(keyHandle, AlgorithmName.ECDH); - ForceSetKeySize(_key.KeySize); - } + /// + /// Label bytes used for the TLS KDF + /// + public byte[]? Label + { + get { return _label; } + set { _label = value; } + } - private void ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters) - { - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_ECCPRIVATE_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_ECCPUBLIC_BLOB; + /// + /// Bytes to append to the raw secret agreement before processing by the KDF + /// + public byte[]? SecretAppend + { + get { return _secretAppend; } + set { _secretAppend = value; } + } - SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecKeyBlob, curveName); + /// + /// Bytes to prepend to the raw secret agreement before processing by the KDF + /// + public byte[]? SecretPrepend + { + get { return _secretPrepend; } + set { _secretPrepend = value; } + } - Debug.Assert(!keyHandle.IsInvalid); + /// + /// Seed bytes used for the TLS KDF + /// + public byte[]? Seed + { + get { return _seed; } + set { _seed = value; } + } - _key.SetHandle(keyHandle, ECCng.EcdhCurveNameToAlgorithm(curveName)); - ForceSetKeySize(_key.KeySize); - } + /// + /// Use the secret agreement as the HMAC key rather than supplying a seperate one + /// + public bool UseSecretAgreementAsHmacKey + { + get { return HmacKey == null; } + } - private byte[] ExportKeyBlob(bool includePrivateParameters) - { - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_ECCPRIVATE_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_ECCPUBLIC_BLOB; + protected override void Dispose(bool disposing) + { + _core.Dispose(); + } - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportKeyBlob(keyHandle, blobType); - } - } + private void ThrowIfDisposed() + { + _core.ThrowIfDisposed(); + } - private byte[] ExportFullKeyBlob(bool includePrivateParameters) - { - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPRIVATE_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPUBLIC_BLOB; + private void DisposeKey() + { + _core.DisposeKey(); + } - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportKeyBlob(keyHandle, blobType); - } - } + internal string? GetCurveName(out string? oidValue) + { + return Key.GetCurveName(out oidValue); + } - private byte[] ExportEncryptedPkcs8(ReadOnlySpan pkcs8Password, int kdfCount) - { - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportPkcs8KeyBlob(keyHandle, pkcs8Password, kdfCount); - } - } + private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters) + { + Key = ECCng.ImportFullKeyBlob(ecfullKeyBlob, includePrivateParameters); + } - private bool TryExportEncryptedPkcs8( - ReadOnlySpan pkcs8Password, - int kdfCount, - Span destination, - out int bytesWritten) - { - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.TryExportPkcs8KeyBlob( - keyHandle, - pkcs8Password, - kdfCount, - destination, - out bytesWritten); - } - } + private void ImportKeyBlob(byte[] ecfullKeyBlob, string curveName, bool includePrivateParameters) + { + Key = ECCng.ImportKeyBlob(ecfullKeyBlob, curveName, includePrivateParameters); + } - private void AcceptImport(CngPkcs8.Pkcs8Response response) - { - SafeNCryptKeyHandle keyHandle = response.KeyHandle; + private byte[] ExportKeyBlob(bool includePrivateParameters) + { + return ECCng.ExportKeyBlob(Key, includePrivateParameters); + } - _key.SetHandle( - keyHandle, - CngKeyLite.GetPropertyAsString( - keyHandle, - CngKeyLite.KeyPropertyName.Algorithm, - CngPropertyOptions.None)); + private byte[] ExportFullKeyBlob(bool includePrivateParameters) + { + return ECCng.ExportFullKeyBlob(Key, includePrivateParameters); + } - ForceSetKeySize(_key.KeySize); - } + private void AcceptImport(CngPkcs8.Pkcs8Response response) + { + Key = response.Key; + } + + public override bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritten) + { + return Key.TryExportKeyBlob( + Interop.NCrypt.NCRYPT_PKCS8_PRIVATE_KEY_BLOB, + destination, + out bytesWritten); + } + + private byte[] ExportEncryptedPkcs8(ReadOnlySpan pkcs8Password, int kdfCount) + { + return Key.ExportPkcs8KeyBlob(pkcs8Password, kdfCount); + } + + private bool TryExportEncryptedPkcs8( + ReadOnlySpan pkcs8Password, + int kdfCount, + Span destination, + out int bytesWritten) + { + return Key.TryExportPkcs8KeyBlob( + pkcs8Password, + kdfCount, + destination, + out bytesWritten); } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs index 99bdc7604bc069..886e5161f0af0c 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanCngPublicKey.cs @@ -1,90 +1,155 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; +using System.Runtime.Versioning; namespace System.Security.Cryptography { - internal static partial class ECDiffieHellmanImplementation + /// + /// Public key used to do key exchange with the ECDiffieHellmanCng algorithm + /// + public sealed partial class ECDiffieHellmanCngPublicKey : ECDiffieHellmanPublicKey { - public sealed partial class ECDiffieHellmanCngPublicKey : ECDiffieHellmanPublicKey + private readonly CngKeyBlobFormat _format; + private readonly string? _curveName; + private bool _disposed; + + /// + /// Wrap a CNG key + /// + internal ECDiffieHellmanCngPublicKey(byte[] keyBlob, string? curveName, CngKeyBlobFormat format) : base(keyBlob) { - private byte[] _keyBlob; - internal string? _curveName; + _format = format; + // Can be null for P256, P384, P521, or an explicit blob + _curveName = curveName; + } - protected override void Dispose(bool disposing) + protected override void Dispose(bool disposing) + { + if (disposing) { - _keyBlob = null!; - base.Dispose(disposing); + _disposed = true; } - public override string ToXmlString() - { - throw new PlatformNotSupportedException(); - } + base.Dispose(disposing); + } - public static ECDiffieHellmanCngPublicKey FromXmlString(string xml) + public override string ToXmlString() + { + throw new PlatformNotSupportedException(); + } + + public static ECDiffieHellmanCngPublicKey FromXmlString(string xml) + { + throw new PlatformNotSupportedException(); + } + + /// + /// Format the key blob is expressed in + /// + public CngKeyBlobFormat BlobFormat + { + get { - throw new PlatformNotSupportedException(); + return _format; } + } - internal ECDiffieHellmanCngPublicKey(byte[] keyBlob, string? curveName) : base(keyBlob) + /// + /// Hydrate a public key from a blob + /// + [SupportedOSPlatform("windows")] + public static ECDiffieHellmanPublicKey FromByteArray(byte[] publicKeyBlob, CngKeyBlobFormat format) + { + if (publicKeyBlob == null) + throw new ArgumentNullException(nameof(publicKeyBlob)); + if (format == null) + throw new ArgumentNullException(nameof(format)); + + // Verify that the key can import successfully, because we did in the past. + using (CngKey imported = CngKey.Import(publicKeyBlob, format)) { - Debug.Assert(keyBlob != null); + if (imported.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) + { + throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey); + } - _keyBlob = keyBlob; - _curveName = curveName; + return new ECDiffieHellmanCngPublicKey(publicKeyBlob, null, format); } + } - /// - /// Exports the key and explicit curve parameters used by the ECC object into an object. - /// - /// - /// if there was an issue obtaining the curve values. - /// - /// - /// if explicit export is not supported by this platform. Windows 10 or higher is required. - /// - /// The key and explicit curve parameters used by the ECC object. - public override ECParameters ExportExplicitParameters() + internal static ECDiffieHellmanCngPublicKey FromKey(CngKey key) + { + CngKeyBlobFormat format; + string? curveName; + byte[] blob = ECCng.ExportKeyBlob(key, false, out format, out curveName); + return new ECDiffieHellmanCngPublicKey(blob, curveName, format); + } + + /// + /// Import the public key into CNG + /// + /// + public CngKey Import() + { + if (_disposed) { - if (_keyBlob == null) - { - throw new ObjectDisposedException(nameof(ECDiffieHellmanPublicKey)); - } + throw new ObjectDisposedException(nameof(ECDiffieHellmanCngPublicKey)); + } + + return CngKey.Import(ToByteArray(), _curveName, BlobFormat); + } + /// + /// Exports the key and explicit curve parameters used by the ECC object into an object. + /// + /// + /// if there was an issue obtaining the curve values. + /// + /// + /// if explicit export is not supported by this platform. Windows 10 or higher is required. + /// + /// The key and explicit curve parameters used by the ECC object. + public override ECParameters ExportExplicitParameters() + { + using (CngKey key = Import()) + { ECParameters ecparams = default; - ECCng.ExportPrimeCurveParameters(ref ecparams, _keyBlob, includePrivateParameters: false); + byte[] blob = ECCng.ExportFullKeyBlob(key, includePrivateParameters: false); + ECCng.ExportPrimeCurveParameters(ref ecparams, blob, includePrivateParameters: false); return ecparams; } + } - /// - /// Exports the key used by the ECC object into an object. - /// If the key was created as a named curve, the Curve property will contain named curve parameters - /// otherwise it will contain explicit parameters. - /// - /// - /// if there was an issue obtaining the curve values. - /// - /// The key and named curve parameters used by the ECC object. - public override ECParameters ExportParameters() + /// + /// Exports the key used by the ECC object into an object. + /// If the key was created as a named curve, the Curve property will contain named curve parameters + /// otherwise it will contain explicit parameters. + /// + /// + /// if there was an issue obtaining the curve values. + /// + /// The key and named curve parameters used by the ECC object. + public override ECParameters ExportParameters() + { + using (CngKey key = Import()) { - if (_keyBlob == null) - { - throw new ObjectDisposedException(nameof(ECDiffieHellmanPublicKey)); - } + ECParameters ecparams = default; + string? curveName = key.GetCurveName(out _); - if (string.IsNullOrEmpty(_curveName)) + if (string.IsNullOrEmpty(curveName)) { - return ExportExplicitParameters(); + byte[] fullKeyBlob = ECCng.ExportFullKeyBlob(key, includePrivateParameters: false); + ECCng.ExportPrimeCurveParameters(ref ecparams, fullKeyBlob, includePrivateParameters: false); } else { - ECParameters ecparams = default; - ECCng.ExportNamedCurveParameters(ref ecparams, _keyBlob, includePrivateParameters: false); - ecparams.Curve = ECCurve.CreateFromFriendlyName(_curveName); - return ecparams; + byte[] keyBlob = ECCng.ExportKeyBlob(key, includePrivateParameters: false); + ECCng.ExportNamedCurveParameters(ref ecparams, keyBlob, includePrivateParameters: false); + ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName); } + + return ecparams; } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanKeyDerivationFunction.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanKeyDerivationFunction.cs new file mode 100644 index 00000000000000..faa0ead6806b79 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanKeyDerivationFunction.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + /// + /// Key derivation functions used to transform the raw secret agreement into key material + /// + public enum ECDiffieHellmanKeyDerivationFunction + { + Hash, + Hmac, + Tls + } +} diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs similarity index 90% rename from src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs index 86e29e6fa136c9..870e7291563a60 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanOpenSsl.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography @@ -16,6 +17,11 @@ public sealed partial class ECDiffieHellmanOpenSsl : ECDiffieHellman /// is null /// /// is not a valid enveloped EC_KEY* + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public ECDiffieHellmanOpenSsl(SafeEvpPKeyHandle pkeyHandle) { if (pkeyHandle == null) @@ -46,6 +52,11 @@ public ECDiffieHellmanOpenSsl(SafeEvpPKeyHandle pkeyHandle) /// /// A pointer to an OpenSSL EC_KEY* /// is invalid + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public ECDiffieHellmanOpenSsl(IntPtr handle) { if (handle == IntPtr.Zero) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanWrapper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanWrapper.cs new file mode 100644 index 00000000000000..91329c22713baa --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDiffieHellmanWrapper.cs @@ -0,0 +1,209 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; + +namespace System.Security.Cryptography +{ + internal sealed class ECDiffieHellmanWrapper : ECDiffieHellman + { + private readonly ECDiffieHellman _wrapped; + + internal ECDiffieHellmanWrapper(ECDiffieHellman wrapped) + { + Debug.Assert(wrapped != null); + _wrapped = wrapped; + } + + public override string KeyExchangeAlgorithm => _wrapped.KeyExchangeAlgorithm; + + public override string? SignatureAlgorithm => _wrapped.SignatureAlgorithm; + + public override ECDiffieHellmanPublicKey PublicKey => + new ECDiffieHellmanPublicKeyWrapper(_wrapped.PublicKey); + + public override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey) => + _wrapped.DeriveKeyMaterial(Unwrap(otherPartyPublicKey)); + + public override byte[] DeriveKeyFromHash( + ECDiffieHellmanPublicKey otherPartyPublicKey, + HashAlgorithmName hashAlgorithm, + byte[]? secretPrepend, + byte[]? secretAppend) => + _wrapped.DeriveKeyFromHash(Unwrap(otherPartyPublicKey), hashAlgorithm, secretPrepend, secretAppend); + + public override byte[] DeriveKeyFromHmac( + ECDiffieHellmanPublicKey otherPartyPublicKey, + HashAlgorithmName hashAlgorithm, + byte[]? hmacKey, + byte[]? secretPrepend, + byte[]? secretAppend) => + _wrapped.DeriveKeyFromHmac(Unwrap(otherPartyPublicKey), hashAlgorithm, hmacKey, secretPrepend, secretAppend); + + public override byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed) => + _wrapped.DeriveKeyTls(Unwrap(otherPartyPublicKey), prfLabel, prfSeed); + + public override void FromXmlString(string xmlString) => _wrapped.FromXmlString(xmlString); + + public override string ToXmlString(bool includePrivateParameters) => + _wrapped.ToXmlString(includePrivateParameters); + + public override ECParameters ExportParameters(bool includePrivateParameters) => + _wrapped.ExportParameters(includePrivateParameters); + + public override ECParameters ExportExplicitParameters(bool includePrivateParameters) => + _wrapped.ExportExplicitParameters(includePrivateParameters); + + public override void ImportParameters(ECParameters parameters) => + _wrapped.ImportParameters(parameters); + + public override void GenerateKey(ECCurve curve) => _wrapped.GenerateKey(curve); + + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) => + _wrapped.TryExportEncryptedPkcs8PrivateKey(passwordBytes, pbeParameters, destination, out bytesWritten); + + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) => + _wrapped.TryExportEncryptedPkcs8PrivateKey(password, pbeParameters, destination, out bytesWritten); + + // Do not wrap ExportPkcs8PrivateKey, let it fall back to reconstructing it from parameters + // so that the ECDiffieHellman.Create()-returned object uses the same set of attributes on all platforms. + // (CNG adds the key usage attribute to distinguish ECDSA from ECDH) + //public override bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritten) => + // _wrapped.TryExportPkcs8PrivateKey(destination, out bytesWritten); + + public override bool TryExportSubjectPublicKeyInfo(Span destination, out int bytesWritten) => + _wrapped.TryExportSubjectPublicKeyInfo(destination, out bytesWritten); + + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + + public override void ImportPkcs8PrivateKey(ReadOnlySpan source, out int bytesRead) => + _wrapped.ImportPkcs8PrivateKey(source, out bytesRead); + + public override void ImportSubjectPublicKeyInfo(ReadOnlySpan source, out int bytesRead) => + _wrapped.ImportSubjectPublicKeyInfo(source, out bytesRead); + + public override void ImportECPrivateKey(ReadOnlySpan source, out int bytesRead) => + _wrapped.ImportECPrivateKey(source, out bytesRead); + + public override byte[] ExportECPrivateKey() => _wrapped.ExportECPrivateKey(); + + public override bool TryExportECPrivateKey(Span destination, out int bytesWritten) => + _wrapped.TryExportECPrivateKey(destination, out bytesWritten); + + public override void ImportFromPem(ReadOnlySpan input) => _wrapped.ImportFromPem(input); + + public override void ImportFromEncryptedPem(ReadOnlySpan input, ReadOnlySpan password) => + _wrapped.ImportFromEncryptedPem(input, password); + + public override void ImportFromEncryptedPem(ReadOnlySpan input, ReadOnlySpan passwordBytes) => + _wrapped.ImportFromEncryptedPem(input, passwordBytes); + + public override int KeySize + { + get => _wrapped.KeySize; + set => _wrapped.KeySize = value; + } + + public override KeySizes[] LegalKeySizes => _wrapped.LegalKeySizes; + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _wrapped.Dispose(); + } + } + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters) => + _wrapped.ExportEncryptedPkcs8PrivateKey(passwordBytes, pbeParameters); + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters) => + _wrapped.ExportEncryptedPkcs8PrivateKey(password, pbeParameters); + + // Do not wrap ExportPkcs8PrivateKey, let it fall back to reconstructing it from parameters + // so that the ECDiffieHellman.Create()-returned object uses the same set of attributes on all platforms. + // (CNG adds the key usage attribute to distinguish ECDSA from ECDH) + //public override byte[] ExportPkcs8PrivateKey() => _wrapped.ExportPkcs8PrivateKey(); + + public override byte[] ExportSubjectPublicKeyInfo() => _wrapped.ExportSubjectPublicKeyInfo(); + + public override bool Equals(object? obj) => _wrapped.Equals(obj); + + public override int GetHashCode() => _wrapped.GetHashCode(); + + public override string ToString() => _wrapped.ToString()!; + + private static ECDiffieHellmanPublicKey Unwrap(ECDiffieHellmanPublicKey otherPartyPublicKey) + { + if (otherPartyPublicKey is ECDiffieHellmanPublicKeyWrapper wrapper) + { + return wrapper.WrappedKey; + } + + return otherPartyPublicKey; + } + + private sealed class ECDiffieHellmanPublicKeyWrapper : ECDiffieHellmanPublicKey + { + private readonly ECDiffieHellmanPublicKey _wrapped; + + internal ECDiffieHellmanPublicKey WrappedKey => _wrapped; + + internal ECDiffieHellmanPublicKeyWrapper(ECDiffieHellmanPublicKey wrapped) + { + Debug.Assert(wrapped != null); + _wrapped = wrapped; + } + + public override ECParameters ExportParameters() => _wrapped.ExportParameters(); + + public override ECParameters ExportExplicitParameters() => _wrapped.ExportExplicitParameters(); + + public override bool TryExportSubjectPublicKeyInfo(Span destination, out int bytesWritten) => + _wrapped.TryExportSubjectPublicKeyInfo(destination, out bytesWritten); + + public override byte[] ExportSubjectPublicKeyInfo() => + _wrapped.ExportSubjectPublicKeyInfo(); + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _wrapped.Dispose(); + } + } + + public override byte[] ToByteArray() => _wrapped.ToByteArray(); + + public override string ToXmlString() => _wrapped.ToXmlString(); + + public override bool Equals(object? obj) => _wrapped.Equals(obj); + + public override int GetHashCode() => _wrapped.GetHashCode(); + + public override string ToString() => _wrapped.ToString()!; + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.OpenSsl.cs index dbb00ed010b585..850fbf9766b14b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.OpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.OpenSsl.cs @@ -10,7 +10,7 @@ public partial class ECDsa : ECAlgorithm /// public static new partial ECDsa Create() { - return new ECDsaImplementation.ECDsaOpenSsl(); + return new ECDsaWrapper(new ECDsaOpenSsl()); } /// @@ -21,7 +21,7 @@ public partial class ECDsa : ECAlgorithm /// public static partial ECDsa Create(ECCurve curve) { - return new ECDsaImplementation.ECDsaOpenSsl(curve); + return new ECDsaWrapper(new ECDsaOpenSsl(curve)); } /// @@ -32,9 +32,18 @@ public static partial ECDsa Create(ECCurve curve) /// public static partial ECDsa Create(ECParameters parameters) { - ECDsa ec = new ECDsaImplementation.ECDsaOpenSsl(); - ec.ImportParameters(parameters); - return ec; + ECDsa ec = new ECDsaOpenSsl(); + + try + { + ec.ImportParameters(parameters); + return new ECDsaWrapper(ec); + } + catch + { + ec.Dispose(); + throw; + } } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.SecurityTransforms.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.SecurityTransforms.cs new file mode 100644 index 00000000000000..5dcbbde048c242 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.SecurityTransforms.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + public partial class ECDsa : ECAlgorithm + { + /// + /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. + /// + public static new partial ECDsa Create() + { + return new ECDsaImplementation.ECDsaSecurityTransforms(); + } + + /// + /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. + /// + /// + /// The representing the elliptic curve. + /// + public static partial ECDsa Create(ECCurve curve) + { + ECDsa ecdsa = Create(); + ecdsa.GenerateKey(curve); + return ecdsa; + } + + /// + /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. + /// + /// + /// The representing the elliptic curve parameters. + /// + public static partial ECDsa Create(ECParameters parameters) + { + ECDsa ecdsa = Create(); + ecdsa.ImportParameters(parameters); + return ecdsa; + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.Windows.cs new file mode 100644 index 00000000000000..3794ff6be455bd --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsa.Create.Windows.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + public partial class ECDsa : ECAlgorithm + { + /// + /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. + /// + public static new partial ECDsa Create() + { + return new ECDsaWrapper(new ECDsaCng()); + } + + /// + /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. + /// + /// + /// The representing the elliptic curve. + /// + public static partial ECDsa Create(ECCurve curve) + { + return new ECDsaWrapper(new ECDsaCng(curve)); + + } + + /// + /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. + /// + /// + /// The representing the elliptic curve parameters. + /// + public static partial ECDsa Create(ECParameters parameters) + { + ECDsa ec = new ECDsaCng(); + ec.ImportParameters(parameters); + return new ECDsaWrapper(ec); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaCng.Key.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaCng.Key.cs index 4382ec8165581e..aabaf167957532 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaCng.Key.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaCng.Key.cs @@ -1,28 +1,123 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; -using static Internal.NativeCrypto.BCryptNative; - namespace System.Security.Cryptography { - internal static partial class ECDsaImplementation + using Microsoft.Win32.SafeHandles; + using System.Diagnostics; + + public sealed partial class ECDsaCng : ECDsa { - public sealed partial class ECDsaCng : ECDsa + /// + /// Gets the key that will be used by the ECDsa object for any cryptographic operation that it uses. + /// This key object will be disposed if the key is reset, for instance by changing the KeySize + /// property, using ImportParamers to create a new key, or by Disposing of the parent ECDsa object. + /// Therefore, you should make sure that the key object is no longer used in these scenarios. This + /// object will not be the same object as the CngKey passed to the ECDsaCng constructor if that + /// constructor was used, however it will point at the same CNG key. + /// + public CngKey Key + { + get + { + return GetKey(); + } + + private set + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + + if (!IsEccAlgorithmGroup(value.AlgorithmGroup)) + throw new ArgumentException(SR.Cryptography_ArgECDsaRequiresECDsaKey, nameof(value)); + _core.SetKey(value); + + // LegalKeySizes stores the values for either the current named curve or for the three + // curves that use size instead of name + ForceSetKeySize(value.KeySize); + } + } + + public override void GenerateKey(ECCurve curve) { - private readonly ECCngKey _key = new ECCngKey(AlgorithmName.ECDsa, nameof(ECDsa)); + curve.Validate(); + _core.DisposeKey(); - private string? GetCurveName(out string? oidValue) => _key.GetCurveName(KeySize, out oidValue); + if (curve.IsNamed) + { + if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value)); - public override void GenerateKey(ECCurve curve) + // Map curve name to algorithm to support pre-Win10 curves + CngAlgorithm alg = CngKey.EcdsaCurveNameToAlgorithm(curve.Oid.FriendlyName); + if (CngKey.IsECNamedCurve(alg.Algorithm)) + { + CngKey key = _core.GetOrGenerateKey(curve); + ForceSetKeySize(key.KeySize); + } + else + { + int keySize; + // Get the proper KeySize from algorithm name + if (alg == CngAlgorithm.ECDsaP256) + keySize = 256; + else if (alg == CngAlgorithm.ECDsaP384) + keySize = 384; + else if (alg == CngAlgorithm.ECDsaP521) + keySize = 521; + else + { + Debug.Fail($"Unknown algorithm {alg}"); + throw new ArgumentException(SR.Cryptography_InvalidKeySize); + } + _core.GetOrGenerateKey(keySize, alg); + ForceSetKeySize(keySize); + } + } + else if (curve.IsExplicit) { - _key.GenerateKey(curve); - ForceSetKeySize(_key.KeySize); + CngKey key = _core.GetOrGenerateKey(curve); + ForceSetKeySize(key.KeySize); } + else + { + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); + } + } - private SafeNCryptKeyHandle GetDuplicatedKeyHandle() => _key.GetDuplicatedKeyHandle(KeySize); + private CngKey GetKey() + { + CngKey key; - private void DisposeKey() => _key.DisposeKey(); + if (_core.IsKeyGeneratedNamedCurve()) + { + // Curve was previously created, so use that + key = _core.GetOrGenerateKey(null); + } + else + { + CngAlgorithm algorithm; + + // Map the current key size to a CNG algorithm name + int keySize = KeySize; + switch (keySize) + { + case 256: algorithm = CngAlgorithm.ECDsaP256; break; + case 384: algorithm = CngAlgorithm.ECDsaP384; break; + case 521: algorithm = CngAlgorithm.ECDsaP521; break; + default: + Debug.Fail("Should not have invalid key size"); + throw new ArgumentException(SR.Cryptography_InvalidKeySize); + } + key = _core.GetOrGenerateKey(keySize, algorithm); + } + + return key; + } + + private SafeNCryptKeyHandle GetDuplicatedKeyHandle() + { + return Key.Handle; } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaCng.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaCng.cs index 5e9b4fe7bccba4..597f077883686b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaCng.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaCng.cs @@ -1,157 +1,156 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; - -using Microsoft.Win32.SafeHandles; -using static Internal.NativeCrypto.BCryptNative; +using System.IO; +using System.Runtime.Versioning; +using Internal.Cryptography; namespace System.Security.Cryptography { - public partial class ECDsa : ECAlgorithm + public sealed partial class ECDsaCng : ECDsa { + private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(ECDsaCng)); + private CngAlgorithm _hashAlgorithm = CngAlgorithm.Sha256; + /// - /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. + /// Hash algorithm to use when generating a signature over arbitrary data /// - public static new partial ECDsa Create() + public CngAlgorithm HashAlgorithm { - return new ECDsaImplementation.ECDsaCng(); + get + { + return _hashAlgorithm; + } + set + { + _hashAlgorithm = value ?? throw new ArgumentNullException(nameof(value)); + } } /// - /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. + /// Creates a new ECDsaCng object that will use the specified key. The key's + /// must be ECDsa. This constructor + /// creates a copy of the key. Hence, the caller can safely dispose of the + /// passed in key and continue using the ECDsaCng object. /// - /// - /// The representing the elliptic curve. - /// - public static partial ECDsa Create(ECCurve curve) + /// Key to use for ECDsa operations + /// if is not an ECDsa key + /// if is null. + [SupportedOSPlatform("windows")] + public ECDsaCng(CngKey key) { - return new ECDsaImplementation.ECDsaCng(curve); + if (key == null) + throw new ArgumentNullException(nameof(key)); + + if (!IsEccAlgorithmGroup(key.AlgorithmGroup)) + throw new ArgumentException(SR.Cryptography_ArgECDsaRequiresECDsaKey, nameof(key)); + + Key = CngAlgorithmCore.Duplicate(key); } - /// - /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm. - /// - /// - /// The representing the elliptic curve parameters. - /// - public static partial ECDsa Create(ECParameters parameters) + protected override void Dispose(bool disposing) { - ECDsa ec = new ECDsaImplementation.ECDsaCng(); - ec.ImportParameters(parameters); - return ec; + _core.Dispose(); } - } - internal static partial class ECDsaImplementation - { - public sealed partial class ECDsaCng : ECDsa + private void ThrowIfDisposed() { - protected override void Dispose(bool disposing) - { - if (disposing) - { - _key?.FullDispose(); - } + _core.ThrowIfDisposed(); + } - base.Dispose(disposing); - } + private void DisposeKey() + { + _core.DisposeKey(); + } - private void ThrowIfDisposed() - { - _key.ThrowIfDisposed(); - } + private static bool IsEccAlgorithmGroup(CngAlgorithmGroup? algorithmGroup) + { + // Sometimes, when reading from certificates, ECDSA keys get identified as ECDH. + // Windows allows the ECDH keys to perform both key exchange (ECDH) and signing (ECDSA), + // so either value is acceptable for the ECDSA wrapper object. + // + // It is worth noting, however, that ECDSA-identified keys cannot be used for key exchange (ECDH) in CNG. + return algorithmGroup == CngAlgorithmGroup.ECDsa || algorithmGroup == CngAlgorithmGroup.ECDiffieHellman; + } - private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters) - { - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPRIVATE_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPUBLIC_BLOB; + internal string? GetCurveName(out string? oidValue) + { + return Key.GetCurveName(out oidValue); + } + + private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters) + { + Key = ECCng.ImportFullKeyBlob(ecfullKeyBlob, includePrivateParameters); + } + + private void ImportKeyBlob(byte[] ecfullKeyBlob, string curveName, bool includePrivateParameters) + { + Key = ECCng.ImportKeyBlob(ecfullKeyBlob, curveName, includePrivateParameters); + } - SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecfullKeyBlob); + private byte[] ExportKeyBlob(bool includePrivateParameters) + { + return ECCng.ExportKeyBlob(Key, includePrivateParameters); + } - Debug.Assert(!keyHandle.IsInvalid); + private byte[] ExportFullKeyBlob(bool includePrivateParameters) + { + return ECCng.ExportFullKeyBlob(Key, includePrivateParameters); + } - _key.SetHandle(keyHandle, AlgorithmName.ECDsa); - ForceSetKeySize(_key.KeySize); - } + private void AcceptImport(CngPkcs8.Pkcs8Response response) + { + Key = response.Key; + } - private void ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters) - { - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_ECCPRIVATE_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_ECCPUBLIC_BLOB; + public override bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritten) + { + return Key.TryExportKeyBlob( + Interop.NCrypt.NCRYPT_PKCS8_PRIVATE_KEY_BLOB, + destination, + out bytesWritten); + } - SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecKeyBlob, curveName); + private byte[] ExportEncryptedPkcs8(ReadOnlySpan pkcs8Password, int kdfCount) + { + return Key.ExportPkcs8KeyBlob(pkcs8Password, kdfCount); + } - Debug.Assert(!keyHandle.IsInvalid); + private bool TryExportEncryptedPkcs8( + ReadOnlySpan pkcs8Password, + int kdfCount, + Span destination, + out int bytesWritten) + { + return Key.TryExportPkcs8KeyBlob( + pkcs8Password, + kdfCount, + destination, + out bytesWritten); + } - _key.SetHandle(keyHandle, ECCng.EcdsaCurveNameToAlgorithm(curveName)); - ForceSetKeySize(_key.KeySize); - } + public void FromXmlString(string xml, ECKeyXmlFormat format) + => throw new PlatformNotSupportedException(); - private byte[] ExportKeyBlob(bool includePrivateParameters) - { - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_ECCPRIVATE_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_ECCPUBLIC_BLOB; - - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportKeyBlob(keyHandle, blobType); - } - } + public byte[] SignData(byte[] data) + => SignData(data, new HashAlgorithmName(HashAlgorithm.Algorithm)); - private byte[] ExportFullKeyBlob(bool includePrivateParameters) - { - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPRIVATE_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_ECCFULLPUBLIC_BLOB; - - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportKeyBlob(keyHandle, blobType); - } - } + public byte[] SignData(byte[] data, int offset, int count) => + SignData(data, offset, count, new HashAlgorithmName(HashAlgorithm.Algorithm)); - private byte[] ExportEncryptedPkcs8(ReadOnlySpan pkcs8Password, int kdfCount) - { - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportPkcs8KeyBlob(keyHandle, pkcs8Password, kdfCount); - } - } + public byte[] SignData(Stream data) + => SignData(data, new HashAlgorithmName(HashAlgorithm.Algorithm)); - private bool TryExportEncryptedPkcs8( - ReadOnlySpan pkcs8Password, - int kdfCount, - Span destination, - out int bytesWritten) - { - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.TryExportPkcs8KeyBlob( - keyHandle, - pkcs8Password, - kdfCount, - destination, - out bytesWritten); - } - } + public string ToXmlString(ECKeyXmlFormat format) + => throw new PlatformNotSupportedException(); - private void AcceptImport(CngPkcs8.Pkcs8Response response) - { - SafeNCryptKeyHandle keyHandle = response.KeyHandle; + public bool VerifyData(byte[] data, byte[] signature) + => VerifyData(data, signature, new HashAlgorithmName(HashAlgorithm.Algorithm)); - _key.SetHandle( - keyHandle, - CngKeyLite.GetPropertyAsString( - keyHandle, - CngKeyLite.KeyPropertyName.Algorithm, - CngPropertyOptions.None)); + public bool VerifyData(byte[] data, int offset, int count, byte[] signature) + => VerifyData(data, offset, count, signature, new HashAlgorithmName(HashAlgorithm.Algorithm)); - ForceSetKeySize(_key.KeySize); - } - } + public bool VerifyData(Stream data, byte[] signature) + => VerifyData(data, signature, new HashAlgorithmName(HashAlgorithm.Algorithm)); } } diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/ECDsaOpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaOpenSsl.cs similarity index 90% rename from src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/ECDsaOpenSsl.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaOpenSsl.cs index 27c08d7dfabb6b..aeac93ad1637f3 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/ECDsaOpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaOpenSsl.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography @@ -16,6 +17,11 @@ public sealed partial class ECDsaOpenSsl : ECDsa /// is null /// /// is not a valid enveloped EC_KEY* + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public ECDsaOpenSsl(SafeEvpPKeyHandle pkeyHandle) { if (pkeyHandle == null) @@ -46,6 +52,11 @@ public ECDsaOpenSsl(SafeEvpPKeyHandle pkeyHandle) /// /// A pointer to an OpenSSL EC_KEY* /// is invalid + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public ECDsaOpenSsl(IntPtr handle) { if (handle == IntPtr.Zero) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaWrapper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaWrapper.cs new file mode 100644 index 00000000000000..ae194055f1d588 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECDsaWrapper.cs @@ -0,0 +1,190 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.IO; +using Internal.Cryptography; + +namespace System.Security.Cryptography +{ + internal sealed partial class ECDsaWrapper : ECDsa + { + private readonly ECDsa _wrapped; + + internal ECDsaWrapper(ECDsa wrapped) + { + Debug.Assert(wrapped != null); + _wrapped = wrapped; + } + + public override byte[] SignData(byte[] data, HashAlgorithmName hashAlgorithm) => + _wrapped.SignData(data, hashAlgorithm); + + public override byte[] SignData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => + _wrapped.SignData(data, offset, count, hashAlgorithm); + + public override bool TrySignData( + ReadOnlySpan data, + Span destination, + HashAlgorithmName hashAlgorithm, + out int bytesWritten) => + _wrapped.TrySignData(data, destination, hashAlgorithm, out bytesWritten); + + public override byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm) => + _wrapped.SignData(data, hashAlgorithm); + + public override bool VerifyData( + byte[] data, + int offset, + int count, + byte[] signature, + HashAlgorithmName hashAlgorithm) => + _wrapped.VerifyData(data, offset, count, signature, hashAlgorithm); + + public override bool VerifyData( + ReadOnlySpan data, + ReadOnlySpan signature, + HashAlgorithmName hashAlgorithm) => + _wrapped.VerifyData(data, signature, hashAlgorithm); + + public override byte[] SignHash(byte[] hash) => _wrapped.SignHash(hash); + + public override bool VerifyHash(byte[] hash, byte[] signature) => _wrapped.VerifyHash(hash, signature); + + public override string? KeyExchangeAlgorithm => _wrapped.KeyExchangeAlgorithm; + + public override void FromXmlString(string xmlString) => _wrapped.FromXmlString(xmlString); + + public override string ToXmlString(bool includePrivateParameters) => + _wrapped.ToXmlString(includePrivateParameters); + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _wrapped.Dispose(); + } + } + + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + + public override void ImportPkcs8PrivateKey( + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportPkcs8PrivateKey(source, out bytesRead); + + public override void ImportSubjectPublicKeyInfo( + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportSubjectPublicKeyInfo(source, out bytesRead); + + public override unsafe void ImportECPrivateKey( + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportECPrivateKey(source, out bytesRead); + + public override byte[] ExportECPrivateKey() => _wrapped.ExportECPrivateKey(); + + public override bool TryExportECPrivateKey( + Span destination, + out int bytesWritten) => + _wrapped.TryExportECPrivateKey(destination, out bytesWritten); + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters) => + _wrapped.ExportEncryptedPkcs8PrivateKey(passwordBytes, pbeParameters); + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters) => + _wrapped.ExportEncryptedPkcs8PrivateKey(password, pbeParameters); + + // Do not wrap ExportPkcs8PrivateKey, let it fall back to reconstructing it from parameters + // so that the ECDsa.Create()-returned object uses the same set of attributes on all platforms. + // (CNG adds the key usage attribute to distinguish ECDSA from ECDH) + //public override byte[] ExportPkcs8PrivateKey() => _wrapped.ExportPkcs8PrivateKey(); + + public override byte[] ExportSubjectPublicKeyInfo() => _wrapped.ExportSubjectPublicKeyInfo(); + + public override ECParameters ExportParameters(bool includePrivateParameters) => + _wrapped.ExportParameters(includePrivateParameters); + + public override ECParameters ExportExplicitParameters(bool includePrivateParameters) => + _wrapped.ExportExplicitParameters(includePrivateParameters); + + public override void ImportParameters(ECParameters parameters) => + _wrapped.ImportParameters(parameters); + + public override void GenerateKey(ECCurve curve) => _wrapped.GenerateKey(curve); + + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) => + _wrapped.TryExportEncryptedPkcs8PrivateKey(passwordBytes, pbeParameters, destination, out bytesWritten); + + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) => + _wrapped.TryExportEncryptedPkcs8PrivateKey(password, pbeParameters, destination, out bytesWritten); + + // Do not wrap TryExportPkcs8PrivateKey, let it fall back to reconstructing it from parameters + // so that the ECDsa.Create()-returned object uses the same set of attributes on all platforms. + // (CNG adds the key usage attribute to distinguish ECDSA from ECDH) + //public override bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritten) => + // _wrapped.TryExportPkcs8PrivateKey(destination, out bytesWritten); + + public override bool TryExportSubjectPublicKeyInfo(Span destination, out int bytesWritten) => + _wrapped.TryExportSubjectPublicKeyInfo(destination, out bytesWritten); + + public override void ImportFromEncryptedPem(ReadOnlySpan input, ReadOnlySpan password) => + _wrapped.ImportFromEncryptedPem(input, password); + + public override void ImportFromEncryptedPem(ReadOnlySpan input, ReadOnlySpan passwordBytes) => + _wrapped.ImportFromEncryptedPem(input, passwordBytes); + + public override void ImportFromPem(ReadOnlySpan input) => _wrapped.ImportFromPem(input); + + public override int KeySize + { + get => _wrapped.KeySize; + set => _wrapped.KeySize = value; + } + + public override KeySizes[] LegalKeySizes => _wrapped.LegalKeySizes; + + public override string SignatureAlgorithm => _wrapped.SignatureAlgorithm; + + public override bool TrySignHash(ReadOnlySpan hash, Span destination, out int bytesWritten) => + _wrapped.TrySignHash(hash, destination, out bytesWritten); + + public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan signature) => + _wrapped.VerifyHash(hash, signature); + + public override bool Equals(object? obj) => _wrapped.Equals(obj); + + public override int GetHashCode() => _wrapped.GetHashCode(); + + public override string ToString() => _wrapped.ToString()!; + + protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) => + AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm); + + protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) => + AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm); + } +} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECKeyXmlFormat.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECKeyXmlFormat.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/ECKeyXmlFormat.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ECKeyXmlFormat.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HKDF.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HKDF.cs index 418bfd2fa25ffe..5c883c6e64acd8 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HKDF.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HKDF.cs @@ -277,23 +277,23 @@ private static int HashLength(HashAlgorithmName hashAlgorithmName) { if (hashAlgorithmName == HashAlgorithmName.SHA1) { - return 160 / 8; + return HMACSHA1.HashSizeInBytes; } else if (hashAlgorithmName == HashAlgorithmName.SHA256) { - return 256 / 8; + return HMACSHA256.HashSizeInBytes; } else if (hashAlgorithmName == HashAlgorithmName.SHA384) { - return 384 / 8; + return HMACSHA384.HashSizeInBytes; } else if (hashAlgorithmName == HashAlgorithmName.SHA512) { - return 512 / 8; + return HMACSHA512.HashSizeInBytes; } else if (hashAlgorithmName == HashAlgorithmName.MD5) { - return 128 / 8; + return HMACMD5.HashSizeInBytes; } else { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs index 19b06adf5b0591..e195a153393924 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Windows.cs @@ -113,35 +113,35 @@ private static unsafe void HashDataUsingPseudoHandle( algHandle = isHmac ? Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_HMAC_MD5_ALG_HANDLE : Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_MD5_ALG_HANDLE; - digestSizeInBytes = 128 / 8; + digestSizeInBytes = MD5.HashSizeInBytes; } else if (hashAlgorithmId == HashAlgorithmNames.SHA1) { algHandle = isHmac ? Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_HMAC_SHA1_ALG_HANDLE : Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA1_ALG_HANDLE; - digestSizeInBytes = 160 / 8; + digestSizeInBytes = SHA1.HashSizeInBytes; } else if (hashAlgorithmId == HashAlgorithmNames.SHA256) { algHandle = isHmac ? Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_HMAC_SHA256_ALG_HANDLE : Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA256_ALG_HANDLE; - digestSizeInBytes = 256 / 8; + digestSizeInBytes = SHA256.HashSizeInBytes; } else if (hashAlgorithmId == HashAlgorithmNames.SHA384) { algHandle = isHmac ? Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_HMAC_SHA384_ALG_HANDLE : Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA384_ALG_HANDLE; - digestSizeInBytes = 384 / 8; + digestSizeInBytes = SHA384.HashSizeInBytes; } else if (hashAlgorithmId == HashAlgorithmNames.SHA512) { algHandle = isHmac ? Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_HMAC_SHA512_ALG_HANDLE : Interop.BCrypt.BCryptAlgPseudoHandle.BCRYPT_SHA512_ALG_HANDLE; - digestSizeInBytes = 512 / 8; + digestSizeInBytes = SHA512.HashSizeInBytes; } else { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Helpers.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Helpers.cs index 76c7608cf0a885..7a60ff24841bb1 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Helpers.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Helpers.cs @@ -2,15 +2,32 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; using System.Diagnostics; -using System.Numerics; +using System.Formats.Asn1; +using System.Globalization; using System.Security.Cryptography; -using System.Security.Cryptography.Asn1; namespace Internal.Cryptography { internal static partial class Helpers { + internal static ReadOnlySpan AsSpanParameter(this byte[] array, string paramName) + { + if (array == null) + throw new ArgumentNullException(paramName); + + return new ReadOnlySpan(array); + } + + internal static void AddRange(this ICollection coll, IEnumerable newData) + { + foreach (T datum in newData) + { + coll.Add(datum); + } + } + public static bool UsesIv(this CipherMode cipherMode) { return cipherMode != CipherMode.ECB; @@ -51,5 +68,267 @@ public static byte[] FixupKeyParity(this byte[] key) } return oddParityKey; } + + internal static byte[] GenerateRandom(int count) + { + byte[] buffer = new byte[count]; + RandomNumberGenerator.Fill(buffer); + return buffer; + } + + // Encode a byte array as an array of upper-case hex characters. + internal static char[] ToHexArrayUpper(this byte[] bytes) + { + char[] chars = new char[bytes.Length * 2]; + HexConverter.EncodeToUtf16(bytes, chars); + return chars; + } + + // Encode a byte array as an upper case hex string. + internal static string ToHexStringUpper(this byte[] bytes) => + Convert.ToHexString(bytes); + + // Decode a hex string-encoded byte array passed to various X509 crypto api. + // The parsing rules are overly forgiving but for compat reasons, they cannot be tightened. + internal static byte[] LaxDecodeHexString(this string hexString) + { + int whitespaceCount = 0; + + ReadOnlySpan s = hexString; + + if (s.Length != 0 && s[0] == '\u200E') + { + s = s.Slice(1); + } + + for (int i = 0; i < s.Length; i++) + { + if (char.IsWhiteSpace(s[i])) + whitespaceCount++; + } + + uint cbHex = (uint)(s.Length - whitespaceCount) / 2; + byte[] hex = new byte[cbHex]; + byte accum = 0; + bool byteInProgress = false; + int index = 0; + + for (int i = 0; i < s.Length; i++) + { + char c = s[i]; + + if (char.IsWhiteSpace(c)) + { + continue; + } + + accum <<= 4; + accum |= (byte)HexConverter.FromChar(c); + + byteInProgress = !byteInProgress; + + // If we've flipped from 0 to 1, back to 0, we have a whole byte + // so add it to the buffer. + if (!byteInProgress) + { + Debug.Assert(index < cbHex, "index < cbHex"); + + hex[index] = accum; + index++; + } + } + + // .NET Framework compat: + // The .NET Framework algorithm removed all whitespace before the loop, then went up to length/2 + // of what was left. This means that in the event of odd-length input the last char is + // ignored, no exception should be raised. + Debug.Assert(index == cbHex, "index == cbHex"); + + return hex; + } + + internal static bool ContentsEqual(this byte[]? a1, byte[]? a2) + { + if (a1 == null) + { + return a2 == null; + } + + if (a2 == null || a1.Length != a2.Length) + { + return false; + } + + return a1.AsSpan().SequenceEqual(a2); + } + + internal static ReadOnlyMemory DecodeOctetStringAsMemory(ReadOnlyMemory encodedOctetString) + { + try + { + ReadOnlySpan input = encodedOctetString.Span; + + if (AsnDecoder.TryReadPrimitiveOctetString( + input, + AsnEncodingRules.BER, + out ReadOnlySpan primitive, + out int consumed)) + { + if (consumed != input.Length) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + if (input.Overlaps(primitive, out int offset)) + { + return encodedOctetString.Slice(offset, primitive.Length); + } + + Debug.Fail("input.Overlaps(primitive) failed after TryReadPrimitiveOctetString succeeded"); + } + + byte[] ret = AsnDecoder.ReadOctetString(input, AsnEncodingRules.BER, out consumed); + + if (consumed != input.Length) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + return ret; + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static bool AreSamePublicECParameters(ECParameters aParameters, ECParameters bParameters) + { + if (aParameters.Curve.CurveType != bParameters.Curve.CurveType) + return false; + + if (!aParameters.Q.X!.ContentsEqual(bParameters.Q.X!) || + !aParameters.Q.Y!.ContentsEqual(bParameters.Q.Y!)) + { + return false; + } + + ECCurve aCurve = aParameters.Curve; + ECCurve bCurve = bParameters.Curve; + + if (aCurve.IsNamed) + { + // On Windows we care about FriendlyName, on Unix we care about Value + return (aCurve.Oid.Value == bCurve.Oid.Value && aCurve.Oid.FriendlyName == bCurve.Oid.FriendlyName); + } + + if (!aCurve.IsExplicit) + { + // Implicit curve, always fail. + return false; + } + + // Ignore Cofactor (which is derivable from the prime or polynomial and Order) + // Ignore Seed and Hash (which are entirely optional, and about how A and B were built) + if (!aCurve.G.X!.ContentsEqual(bCurve.G.X!) || + !aCurve.G.Y!.ContentsEqual(bCurve.G.Y!) || + !aCurve.Order.ContentsEqual(bCurve.Order) || + !aCurve.A.ContentsEqual(bCurve.A) || + !aCurve.B.ContentsEqual(bCurve.B)) + { + return false; + } + + if (aCurve.IsPrime) + { + return aCurve.Prime.ContentsEqual(bCurve.Prime); + } + + if (aCurve.IsCharacteristic2) + { + return aCurve.Polynomial.ContentsEqual(bCurve.Polynomial); + } + + Debug.Fail($"Missing match criteria for curve type {aCurve.CurveType}"); + return false; + } + + internal static bool IsValidDay(this Calendar calendar, int year, int month, int day, int era) + { + return (calendar.IsValidMonth(year, month, era) && day >= 1 && day <= calendar.GetDaysInMonth(year, month, era)); + } + + private static bool IsValidMonth(this Calendar calendar, int year, int month, int era) + { + return (calendar.IsValidYear(year, era) && month >= 1 && month <= calendar.GetMonthsInYear(year, era)); + } + + private static bool IsValidYear(this Calendar calendar, int year, int era) + { + return (year >= calendar.GetYear(calendar.MinSupportedDateTime) && year <= calendar.GetYear(calendar.MaxSupportedDateTime)); + } + + internal static void DisposeAll(this IEnumerable disposables) + { + foreach (IDisposable disposable in disposables) + { + disposable.Dispose(); + } + } + + internal static void ValidateDer(ReadOnlySpan encodedValue) + { + try + { + Asn1Tag tag; + AsnValueReader reader = new AsnValueReader(encodedValue, AsnEncodingRules.DER); + + while (reader.HasData) + { + tag = reader.PeekTag(); + + // If the tag is in the UNIVERSAL class + // + // DER limits the constructed encoding to SEQUENCE and SET, as well as anything which gets + // a defined encoding as being an IMPLICIT SEQUENCE. + if (tag.TagClass == TagClass.Universal) + { + switch ((UniversalTagNumber)tag.TagValue) + { + case UniversalTagNumber.External: + case UniversalTagNumber.Embedded: + case UniversalTagNumber.Sequence: + case UniversalTagNumber.Set: + case UniversalTagNumber.UnrestrictedCharacterString: + if (!tag.IsConstructed) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + break; + default: + if (tag.IsConstructed) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + break; + } + } + + if (tag.IsConstructed) + { + ValidateDer(reader.PeekContentBytes()); + } + + // Skip past the current value. + reader.ReadEncodedValue(); + } + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } } } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ICngSymmetricAlgorithm.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ICngSymmetricAlgorithm.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ICngSymmetricAlgorithm.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ICngSymmetricAlgorithm.cs index fa46b5cd2ad0b1..1e5c3c31465d84 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ICngSymmetricAlgorithm.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ICngSymmetricAlgorithm.cs @@ -1,10 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Security.Cryptography; using Internal.NativeCrypto; -namespace Internal.Cryptography +namespace System.Security.Cryptography { // // Internal interface that allows CngSymmetricAlgorithmCore to communicate back with the SymmetricAlgorithm it's embedded in. diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/ICspAsymmetricAlgorithm.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ICspAsymmetricAlgorithm.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/ICspAsymmetricAlgorithm.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ICspAsymmetricAlgorithm.cs diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/KeyNumber.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/KeyNumber.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/KeyNumber.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/KeyNumber.cs diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/MD5CryptoServiceProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MD5CryptoServiceProvider.cs similarity index 91% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/MD5CryptoServiceProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MD5CryptoServiceProvider.cs index 8b0a74d682f8e0..3342ad70e56382 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/MD5CryptoServiceProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/MD5CryptoServiceProvider.cs @@ -16,14 +16,18 @@ public sealed class MD5CryptoServiceProvider : MD5 public MD5CryptoServiceProvider() { _incrementalHash = IncrementalHash.CreateHash(HashAlgorithmName.MD5); +#pragma warning disable CA1416 // MD5.HashSizeInBits is unsupported on browser HashSizeValue = HashSizeInBits; +#pragma warning restore CA1416 } public override void Initialize() { if (_running) { +#pragma warning disable CA1416 // MD5.HashSizeInBytes is unsupported on browser Span destination = stackalloc byte[HashSizeInBytes]; +#pragma warning restore CA1416 if (!_incrementalHash.TryGetHashAndReset(destination, out _)) { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OpenSsl.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OpenSsl.NotSupported.cs new file mode 100644 index 00000000000000..b5611338e8daa9 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OpenSsl.NotSupported.cs @@ -0,0 +1,270 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +namespace System.Security.Cryptography +{ + public sealed class DSAOpenSsl : DSA + { + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public DSAOpenSsl() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public DSAOpenSsl(int keySize) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public DSAOpenSsl(IntPtr handle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public DSAOpenSsl(DSAParameters parameters) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public DSAOpenSsl(SafeEvpPKeyHandle pkeyHandle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + public SafeEvpPKeyHandle DuplicateKeyHandle() => null!; + public override byte[] CreateSignature(byte[] rgbHash) => null!; + public override DSAParameters ExportParameters(bool includePrivateParameters) => default; + public override void ImportParameters(DSAParameters parameters) { } + public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) => false; + } + public sealed class ECDiffieHellmanOpenSsl : ECDiffieHellman + { + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDiffieHellmanOpenSsl() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDiffieHellmanOpenSsl(int keySize) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDiffieHellmanOpenSsl(IntPtr handle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDiffieHellmanOpenSsl(ECCurve curve) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDiffieHellmanOpenSsl(SafeEvpPKeyHandle pkeyHandle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + public SafeEvpPKeyHandle DuplicateKeyHandle() => null!; + public override ECDiffieHellmanPublicKey PublicKey => null!; + public override ECParameters ExportParameters(bool includePrivateParameters) => default; + public override void ImportParameters(ECParameters parameters) { } + } + public sealed class ECDsaOpenSsl : ECDsa + { + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDsaOpenSsl() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDsaOpenSsl(int keySize) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDsaOpenSsl(IntPtr handle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDsaOpenSsl(ECCurve curve) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public ECDsaOpenSsl(SafeEvpPKeyHandle pkeyHandle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + public SafeEvpPKeyHandle DuplicateKeyHandle() => null!; + public override byte[] SignHash(byte[] hash) => null!; + public override bool VerifyHash(byte[] hash, byte[] signature) => default; + } + public sealed class RSAOpenSsl : RSA + { + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public RSAOpenSsl() + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public RSAOpenSsl(int keySize) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public RSAOpenSsl(IntPtr handle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public RSAOpenSsl(RSAParameters parameters) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + public SafeEvpPKeyHandle DuplicateKeyHandle() => null!; + public override RSAParameters ExportParameters(bool includePrivateParameters) => default; + public override void ImportParameters(RSAParameters parameters) { } + } + public sealed class SafeEvpPKeyHandle : SafeHandle + { + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public SafeEvpPKeyHandle() : base(IntPtr.Zero, false) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public SafeEvpPKeyHandle(IntPtr handle, bool ownsHandle) : base(handle, ownsHandle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + } + + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] + public static long OpenSslVersion => + throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyOpenSSL); + + public SafeEvpPKeyHandle DuplicateHandle() => null!; + public override bool IsInvalid => true; + protected override bool ReleaseHandle() => false; + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OpenSslCipherLite.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OpenSslCipherLite.cs index c378dc81140476..4568c042742081 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OpenSslCipherLite.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OpenSslCipherLite.cs @@ -125,7 +125,7 @@ public unsafe int Transform(ReadOnlySpan input, Span output) public void Reset(ReadOnlySpan iv) { - bool status = Interop.Crypto.EvpCipherReset(_ctx); + bool status = Interop.Crypto.EvpCipherReset(_ctx, iv); CheckBoolReturn(status); #if DEBUG diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PasswordDeriveBytes.NotSupported.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Unix.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PasswordDeriveBytes.NotSupported.cs diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs index c516653016400e..51b244f025dbf9 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PasswordDeriveBytes.Windows.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.NativeCrypto; using System.Runtime.Versioning; #pragma warning disable CA5373 // Call to obsolete key derivation function PasswordDeriveBytes.* diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PasswordDeriveBytes.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/PasswordDeriveBytes.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PasswordDeriveBytes.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PinAndClear.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PinAndClear.cs new file mode 100644 index 00000000000000..43435cda416193 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PinAndClear.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +namespace System.Security.Cryptography +{ + internal struct PinAndClear : IDisposable + { + private byte[] _data; + private GCHandle _gcHandle; + + internal static PinAndClear Track(byte[] data) + { + return new PinAndClear + { + _gcHandle = GCHandle.Alloc( + data, + GCHandleType.Pinned), + _data = data, + }; + } + + public void Dispose() + { + Array.Clear(_data); + _gcHandle.Free(); + } + } +} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ProviderPropertyName.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ProviderPropertyName.cs similarity index 83% rename from src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ProviderPropertyName.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ProviderPropertyName.cs index 7ec02f680d6759..eac3ad6b425668 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/Internal/Cryptography/ProviderPropertyName.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ProviderPropertyName.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Diagnostics; - -namespace Internal.Cryptography +namespace System.Security.Cryptography { /// /// Well known names of provider properties diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RC2CryptoServiceProvider.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RC2CryptoServiceProvider.NotSupported.cs new file mode 100644 index 00000000000000..4fc7781d189b58 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RC2CryptoServiceProvider.NotSupported.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.Versioning; + +namespace System.Security.Cryptography +{ + public sealed partial class RC2CryptoServiceProvider : RC2 + { + [SuppressMessage("Microsoft.Security", "CA5351", Justification = "This is the implementation of RC2CryptoServiceProvider")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + public RC2CryptoServiceProvider() + { + throw new PlatformNotSupportedException(); + } + + public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) => default!; + public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) => default!; + public override void GenerateIV() { } + public override void GenerateKey() { } + + public bool UseSalt + { + get { return false; } + [SupportedOSPlatform("windows")] + set { } + } + } +} diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs similarity index 93% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs index 4aeb4ec3c607be..72e06ca794655a 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RC2CryptoServiceProvider.Unix.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography; using System.Runtime.Versioning; namespace System.Security.Cryptography @@ -16,6 +15,8 @@ public sealed partial class RC2CryptoServiceProvider : RC2 }; [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "This is the implementation of RC2CryptoServiceProvider")] + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] public RC2CryptoServiceProvider() { _impl = RC2.Create(); @@ -32,10 +33,10 @@ public override int BlockSize public override ICryptoTransform CreateEncryptor() => _impl.CreateEncryptor(); public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) => - _impl.CreateEncryptor(rgbKey, Helpers.TrimLargeIV(rgbIV, BlockSize)); + _impl.CreateEncryptor(rgbKey, CapiHelper.TrimLargeIV(rgbIV, BlockSize)); public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) => - _impl.CreateDecryptor(rgbKey, Helpers.TrimLargeIV(rgbIV, BlockSize)); + _impl.CreateDecryptor(rgbKey, CapiHelper.TrimLargeIV(rgbIV, BlockSize)); protected override void Dispose(bool disposing) { diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs index b76119432af1ba..d3da83fa8a6a5c 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RC2CryptoServiceProvider.Windows.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography; -using Internal.NativeCrypto; using System.ComponentModel; using System.Diagnostics; using System.Runtime.Versioning; @@ -21,6 +20,8 @@ public sealed class RC2CryptoServiceProvider : RC2 new KeySizes(40, 128, 8) // csp implementation only goes up to 128 }; + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] public RC2CryptoServiceProvider() { LegalKeySizesValue = s_legalKeySizes.CloneKeySizesArray(); diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RNGCryptoServiceProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RNGCryptoServiceProvider.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RNGCryptoServiceProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RNGCryptoServiceProvider.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.Create.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.Create.OpenSsl.cs new file mode 100644 index 00000000000000..ba66ba58fe0782 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.Create.OpenSsl.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + public partial class RSA : AsymmetricAlgorithm + { + public static new partial RSA Create() + { + return new RSAWrapper(new RSAOpenSsl()); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.Create.SecurityTransforms.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.Create.SecurityTransforms.cs new file mode 100644 index 00000000000000..a53e3e1b3cf3ae --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.Create.SecurityTransforms.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + public partial class RSA : AsymmetricAlgorithm + { + public static new partial RSA Create() + { + return new RSAImplementation.RSASecurityTransforms(); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.Create.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.Create.Windows.cs new file mode 100644 index 00000000000000..1871e87f87c66a --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.Create.Windows.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography +{ + public partial class RSA : AsymmetricAlgorithm + { + public static new partial RSA Create() + { + return new RSAWrapper(new RSACng()); + } + } +} diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/RSACng.ImportExport.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACng.ImportExport.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/RSACng.ImportExport.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACng.ImportExport.cs diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/RSACng.Key.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACng.Key.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/RSACng.Key.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACng.Key.cs diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACng.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACng.cs index a3297868525192..6038ea68ce7e14 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACng.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACng.cs @@ -1,153 +1,44 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; - -using Microsoft.Win32.SafeHandles; +using System.Runtime.Versioning; +using Internal.Cryptography; namespace System.Security.Cryptography { - public partial class RSA : AsymmetricAlgorithm - { - public static new partial RSA Create() - { - return new RSAImplementation.RSACng(); - } - } - - internal static partial class RSAImplementation + public sealed partial class RSACng : RSA { - public sealed partial class RSACng : RSA + private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(RSACng)); + + /// + /// Creates a new RSACng object that will use the specified key. The key's + /// must be Rsa. This constructor + /// creates a copy of the key. Hence, the caller can safely dispose of the + /// passed in key and continue using the RSACng object. + /// + /// Key to use for RSA operations + /// if is not an RSA key + /// if is null. + [SupportedOSPlatform("windows")] + public RSACng(CngKey key) { - private SafeNCryptKeyHandle? _keyHandle; - private int _lastKeySize; - private bool _disposed; - - private void ThrowIfDisposed() - { - if (_disposed) - { - throw new ObjectDisposedException(nameof(RSA)); - } - } - - private SafeNCryptKeyHandle GetDuplicatedKeyHandle() - { - ThrowIfDisposed(); - - int keySize = KeySize; - - if (_lastKeySize != keySize) - { - if (_keyHandle != null) - { - _keyHandle.Dispose(); - } - - const string BCRYPT_RSA_ALGORITHM = "RSA"; - - _keyHandle = CngKeyLite.GenerateNewExportableKey(BCRYPT_RSA_ALGORITHM, keySize); - _lastKeySize = keySize; - } - - return new DuplicateSafeNCryptKeyHandle(_keyHandle!); - } - - private byte[] ExportKeyBlob(bool includePrivateParameters) - { - string blobType = includePrivateParameters ? - Interop.BCrypt.KeyBlobType.BCRYPT_RSAFULLPRIVATE_BLOB : - Interop.BCrypt.KeyBlobType.BCRYPT_RSAPUBLIC_KEY_BLOB; - - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportKeyBlob(keyHandle, blobType); - } - } + if (key == null) + throw new ArgumentNullException(nameof(key)); - private byte[] ExportEncryptedPkcs8(ReadOnlySpan pkcs8Password, int kdfCount) - { - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.ExportPkcs8KeyBlob(keyHandle, pkcs8Password, kdfCount); - } - } + if (key.AlgorithmGroup != CngAlgorithmGroup.Rsa) + throw new ArgumentException(SR.Cryptography_ArgRSARequiresRSAKey, nameof(key)); - private bool TryExportEncryptedPkcs8( - ReadOnlySpan pkcs8Password, - int kdfCount, - Span destination, - out int bytesWritten) - { - using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) - { - return CngKeyLite.TryExportPkcs8KeyBlob( - keyHandle, - pkcs8Password, - kdfCount, - destination, - out bytesWritten); - } - } - - private void ImportKeyBlob(byte[] rsaBlob, bool includePrivate) - { - ThrowIfDisposed(); - - string blobType = includePrivate - ? Interop.BCrypt.KeyBlobType.BCRYPT_RSAPRIVATE_BLOB - : Interop.BCrypt.KeyBlobType.BCRYPT_RSAPUBLIC_KEY_BLOB; - - SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, rsaBlob); - SetKeyHandle(keyHandle); - } - - private void AcceptImport(CngPkcs8.Pkcs8Response response) - { - ThrowIfDisposed(); - - SafeNCryptKeyHandle keyHandle = response.KeyHandle; - SetKeyHandle(keyHandle); - } - - private void SetKeyHandle(SafeNCryptKeyHandle keyHandle) - { - Debug.Assert(!keyHandle.IsInvalid); - - _keyHandle = keyHandle; - - int newKeySize = CngKeyLite.GetKeyLength(keyHandle); - - // Our LegalKeySizes value stores the values that we encoded as being the correct - // legal key size limitations for this algorithm, as documented on MSDN. - // - // But on a new OS version we might not question if our limit is accurate, or MSDN - // could have been inaccurate to start with. - // - // Since the key is already loaded, we know that Windows thought it to be valid; - // therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance - // check. - // - // For RSA there are known cases where this change matters. RSACryptoServiceProvider can - // create a 384-bit RSA key, which we consider too small to be legal. It can also create - // a 1032-bit RSA key, which we consider illegal because it doesn't match our 64-bit - // alignment requirement. (In both cases Windows loads it just fine) - ForceSetKeySize(newKeySize); - _lastKeySize = newKeySize; - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - _keyHandle?.Dispose(); - _keyHandle = null!; - _disposed = true; - } + Key = CngAlgorithmCore.Duplicate(key); + } + protected override void Dispose(bool disposing) + { + _core.Dispose(); + } - base.Dispose(disposing); - } + private void ThrowIfDisposed() + { + _core.ThrowIfDisposed(); } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.NotSupported.cs new file mode 100644 index 00000000000000..4be85c451896d5 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.NotSupported.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.IO; +using System.Runtime.Versioning; + +namespace System.Security.Cryptography +{ + public sealed partial class RSACryptoServiceProvider : RSA, ICspAsymmetricAlgorithm + { + [UnsupportedOSPlatform("browser")] + public RSACryptoServiceProvider() + { + throw new PlatformNotSupportedException(); + } + + [UnsupportedOSPlatform("browser")] + public RSACryptoServiceProvider(int dwKeySize) + { + throw new PlatformNotSupportedException(); + } + + [SupportedOSPlatform("windows")] + public RSACryptoServiceProvider(int dwKeySize, CspParameters parameters) => + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); + + [SupportedOSPlatform("windows")] + public RSACryptoServiceProvider(CspParameters parameters) => + throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CAPI_Required, nameof(CspParameters))); + + [SupportedOSPlatform("windows")] + public CspKeyContainerInfo CspKeyContainerInfo => default!; + + public byte[] Decrypt(byte[] rgb, bool fOAEP) => default!; + public byte[] Encrypt(byte[] rgb, bool fOAEP) => default!; + public byte[] ExportCspBlob(bool includePrivateParameters) => default!; + public override RSAParameters ExportParameters(bool includePrivateParameters) => default; + public void ImportCspBlob(byte[] keyBlob) { } + public override void ImportParameters(RSAParameters parameters) { } + public bool PersistKeyInCsp { get; set; } + public bool PublicOnly => default; + public byte[] SignData(byte[] buffer, object halg) => default!; + public byte[] SignData(byte[] buffer, int offset, int count, object halg) => default!; + public byte[] SignData(Stream inputStream, object halg) => default!; + public byte[] SignHash(byte[] rgbHash, string str) => default!; + public bool VerifyData(byte[] buffer, object halg, byte[] signature) => default; + public bool VerifyHash(byte[] rgbHash, string str, byte[] rgbSignature) => default; + + // UseMachineKeyStore has no effect in non-Windows + public static bool UseMachineKeyStore { get; set; } + } +} diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs index 168a456800e5bc..70ba680b3f6fdd 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Unix.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography; -using Internal.NativeCrypto; using System.IO; using System.Runtime.Versioning; @@ -15,9 +14,11 @@ public sealed partial class RSACryptoServiceProvider : RSA, ICspAsymmetricAlgori private readonly RSA _impl; private bool _publicOnly; + [UnsupportedOSPlatform("browser")] public RSACryptoServiceProvider() : this(DefaultKeySize) { } + [UnsupportedOSPlatform("browser")] public RSACryptoServiceProvider(int dwKeySize) { if (dwKeySize < 0) @@ -205,13 +206,13 @@ public override bool TrySignData(ReadOnlySpan data, Span destination _impl.TrySignData(data, destination, hashAlgorithm, padding, out bytesWritten); public byte[] SignData(byte[] buffer, int offset, int count, object halg) => - _impl.SignData(buffer, offset, count, HashAlgorithmNames.ObjToHashAlgorithmName(halg), RSASignaturePadding.Pkcs1); + _impl.SignData(buffer, offset, count, CapiHelper.ObjToHashAlgorithmName(halg), RSASignaturePadding.Pkcs1); public byte[] SignData(byte[] buffer, object halg) => - _impl.SignData(buffer, HashAlgorithmNames.ObjToHashAlgorithmName(halg), RSASignaturePadding.Pkcs1); + _impl.SignData(buffer, CapiHelper.ObjToHashAlgorithmName(halg), RSASignaturePadding.Pkcs1); public byte[] SignData(Stream inputStream, object halg) => - _impl.SignData(inputStream, HashAlgorithmNames.ObjToHashAlgorithmName(halg), RSASignaturePadding.Pkcs1); + _impl.SignData(inputStream, CapiHelper.ObjToHashAlgorithmName(halg), RSASignaturePadding.Pkcs1); public override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) => padding == null ? throw new ArgumentNullException(nameof(padding)) : @@ -230,14 +231,14 @@ public byte[] SignHash(byte[] rgbHash, string str) if (PublicOnly) throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); - HashAlgorithmName algName = HashAlgorithmNames.NameOrOidToHashAlgorithmName(str); + HashAlgorithmName algName = CapiHelper.NameOrOidToHashAlgorithmName(str); return _impl.SignHash(rgbHash, algName, RSASignaturePadding.Pkcs1); } public override string ToXmlString(bool includePrivateParameters) => _impl.ToXmlString(includePrivateParameters); public bool VerifyData(byte[] buffer, object halg, byte[] signature) => - _impl.VerifyData(buffer, signature, HashAlgorithmNames.ObjToHashAlgorithmName(halg), RSASignaturePadding.Pkcs1); + _impl.VerifyData(buffer, signature, CapiHelper.ObjToHashAlgorithmName(halg), RSASignaturePadding.Pkcs1); public override bool VerifyData(byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) => padding == null ? throw new ArgumentNullException(nameof(padding)) : @@ -281,7 +282,7 @@ public bool VerifyHash(byte[] rgbHash, string str, byte[] rgbSignature) return VerifyHash( (ReadOnlySpan)rgbHash, (ReadOnlySpan)rgbSignature, - HashAlgorithmNames.NameOrOidToHashAlgorithmName(str), RSASignaturePadding.Pkcs1); + CapiHelper.NameOrOidToHashAlgorithmName(str), RSASignaturePadding.Pkcs1); } // UseMachineKeyStore has no effect in Unix diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs index 005988e00c8f17..ed045ea21a9ce7 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSACryptoServiceProvider.Windows.cs @@ -6,9 +6,6 @@ using System.IO; using System.Runtime.Versioning; using Internal.Cryptography; -using Internal.NativeCrypto; -using Microsoft.Win32.SafeHandles; -using static Internal.NativeCrypto.CapiHelper; namespace System.Security.Cryptography { @@ -17,11 +14,12 @@ public sealed partial class RSACryptoServiceProvider : RSA, ICspAsymmetricAlgori private int _keySize; private readonly CspParameters _parameters; private readonly bool _randomKeyContainer; - private SafeKeyHandle? _safeKeyHandle; + private SafeCapiKeyHandle? _safeKeyHandle; private SafeProvHandle? _safeProvHandle; private static volatile CspProviderFlags s_useMachineKeyStore; private bool _disposed; + [UnsupportedOSPlatform("browser")] public RSACryptoServiceProvider() : this(0, new CspParameters(CapiHelper.DefaultRsaProviderType, null, @@ -31,6 +29,7 @@ public RSACryptoServiceProvider() { } + [UnsupportedOSPlatform("browser")] public RSACryptoServiceProvider(int dwKeySize) : this(dwKeySize, new CspParameters(CapiHelper.DefaultRsaProviderType, @@ -72,7 +71,7 @@ private RSACryptoServiceProvider(int keySize, CspParameters? parameters, bool us if (!_randomKeyContainer) { // Force-read the SafeKeyHandle property, which will summon it into existence. - SafeKeyHandle localHandle = SafeKeyHandle; + SafeCapiKeyHandle localHandle = SafeKeyHandle; Debug.Assert(localHandle != null); } } @@ -115,7 +114,7 @@ private SafeProvHandle SafeProvHandle if (current != null) { - SafeKeyHandle? keyHandle = _safeKeyHandle; + SafeCapiKeyHandle? keyHandle = _safeKeyHandle; _safeKeyHandle = null; keyHandle?.Dispose(); current.Dispose(); @@ -126,7 +125,7 @@ private SafeProvHandle SafeProvHandle } } - private SafeKeyHandle SafeKeyHandle + private SafeCapiKeyHandle SafeKeyHandle { get { @@ -136,7 +135,7 @@ private SafeKeyHandle SafeKeyHandle { if (_safeKeyHandle == null) { - SafeKeyHandle hKey = CapiHelper.GetKeyPairHelper( + SafeCapiKeyHandle hKey = CapiHelper.GetKeyPairHelper( CapiHelper.CspAlgorithmType.Rsa, _parameters, _keySize, @@ -158,7 +157,7 @@ private SafeKeyHandle SafeKeyHandle { lock (_parameters) { - SafeKeyHandle? current = _safeKeyHandle; + SafeCapiKeyHandle? current = _safeKeyHandle; if (ReferenceEquals(value, current)) { @@ -181,7 +180,7 @@ public CspKeyContainerInfo CspKeyContainerInfo { // .NET Framework compat: Read the SafeKeyHandle property to force the key to load, // because it might throw here. - SafeKeyHandle localHandle = SafeKeyHandle; + SafeCapiKeyHandle localHandle = SafeKeyHandle; Debug.Assert(localHandle != null); return new CspKeyContainerInfo(_parameters, _randomKeyContainer); @@ -195,7 +194,7 @@ public override int KeySize { get { - byte[] keySize = CapiHelper.GetKeyParameter(SafeKeyHandle, Constants.CLR_KEYLEN); + byte[] keySize = CapiHelper.GetKeyParameter(SafeKeyHandle, CapiHelper.ClrPropertyId.CLR_KEYLEN); _keySize = BinaryPrimitives.ReadInt32LittleEndian(keySize); return _keySize; } @@ -236,7 +235,7 @@ public bool PublicOnly { get { - byte[] publicKey = CapiHelper.GetKeyParameter(SafeKeyHandle, Constants.CLR_PUBLICKEYONLY); + byte[] publicKey = CapiHelper.GetKeyParameter(SafeKeyHandle, CapiHelper.ClrPropertyId.CLR_PUBLICKEYONLY); return (publicKey[0] == 1); } } @@ -385,7 +384,7 @@ private SafeProvHandle AcquireSafeProviderHandle() public void ImportCspBlob(byte[] keyBlob) { ThrowIfDisposed(); - SafeKeyHandle safeKeyHandle; + SafeCapiKeyHandle safeKeyHandle; if (IsPublic(keyBlob)) { @@ -443,8 +442,8 @@ public override void ImportEncryptedPkcs8PrivateKey( public byte[] SignData(byte[] buffer, int offset, int count, object halg) { int calgHash = CapiHelper.ObjToHashAlgId(halg); - HashAlgorithm hash = CapiHelper.ObjToHashAlgorithm(halg); - byte[] hashVal = hash.ComputeHash(buffer, offset, count); + HashAlgorithmName hashAlgorithmName = CapiHelper.AlgIdToHashAlgorithmName(calgHash); + byte[] hashVal = HashOneShotHelpers.HashData(hashAlgorithmName, new ReadOnlySpan(buffer, offset, count)); return SignHash(hashVal, calgHash); } @@ -458,8 +457,8 @@ public byte[] SignData(byte[] buffer, int offset, int count, object halg) public byte[] SignData(byte[] buffer, object halg) { int calgHash = CapiHelper.ObjToHashAlgId(halg); - HashAlgorithm hash = CapiHelper.ObjToHashAlgorithm(halg); - byte[] hashVal = hash.ComputeHash(buffer); + HashAlgorithmName hashAlgorithmName = CapiHelper.AlgIdToHashAlgorithmName(calgHash); + byte[] hashVal = HashOneShotHelpers.HashData(hashAlgorithmName, buffer); return SignHash(hashVal, calgHash); } @@ -473,8 +472,8 @@ public byte[] SignData(byte[] buffer, object halg) public byte[] SignData(Stream inputStream, object halg) { int calgHash = CapiHelper.ObjToHashAlgId(halg); - HashAlgorithm hash = CapiHelper.ObjToHashAlgorithm(halg); - byte[] hashVal = hash.ComputeHash(inputStream); + HashAlgorithmName hashAlgorithmName = CapiHelper.AlgIdToHashAlgorithmName(calgHash); + byte[] hashVal = HashOneShotHelpers.HashData(hashAlgorithmName, inputStream); return SignHash(hashVal, calgHash); } @@ -523,8 +522,8 @@ private byte[] SignHash(byte[] rgbHash, int calgHash) public bool VerifyData(byte[] buffer, object halg, byte[] signature) { int calgHash = CapiHelper.ObjToHashAlgId(halg); - HashAlgorithm hash = CapiHelper.ObjToHashAlgorithm(halg); - byte[] hashVal = hash.ComputeHash(buffer); + HashAlgorithmName hashAlgorithmName = CapiHelper.AlgIdToHashAlgorithmName(calgHash); + byte[] hashVal = HashOneShotHelpers.HashData(hashAlgorithmName, buffer); return VerifyHash(hashVal, calgHash, signature); } diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAOpenSsl.cs similarity index 84% rename from src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/RSAOpenSsl.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAOpenSsl.cs index 151dfba522f40f..1ef165c992e8ee 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/src/System/Security/Cryptography/RSAOpenSsl.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAOpenSsl.cs @@ -2,12 +2,18 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { public sealed partial class RSAOpenSsl : RSA { + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public RSAOpenSsl(RSAParameters parameters) { ThrowIfNotSupported(); @@ -27,6 +33,11 @@ public RSAOpenSsl(RSAParameters parameters) /// /// A pointer to an OpenSSL RSA* /// is invalid + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public RSAOpenSsl(IntPtr handle) { if (handle == IntPtr.Zero) @@ -49,6 +60,11 @@ public RSAOpenSsl(IntPtr handle) /// /// /// is not a valid enveloped RSA* + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle) { if (pkeyHandle == null) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAWrapper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAWrapper.cs new file mode 100644 index 00000000000000..88429746640298 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSAWrapper.cs @@ -0,0 +1,219 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.IO; + +namespace System.Security.Cryptography +{ + internal sealed class RSAWrapper : RSA + { + private readonly RSA _wrapped; + + internal RSAWrapper(RSA wrapped) + { + Debug.Assert(wrapped != null); + _wrapped = wrapped; + } + + public override int KeySize + { + get => _wrapped.KeySize; + set => _wrapped.KeySize = value; + } + + public override KeySizes[] LegalKeySizes => _wrapped.LegalKeySizes; + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters) => + _wrapped.ExportEncryptedPkcs8PrivateKey(passwordBytes, pbeParameters); + + public override byte[] ExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters) => + _wrapped.ExportEncryptedPkcs8PrivateKey(password, pbeParameters); + + public override byte[] ExportPkcs8PrivateKey() => _wrapped.ExportPkcs8PrivateKey(); + + public override byte[] ExportSubjectPublicKeyInfo() => _wrapped.ExportSubjectPublicKeyInfo(); + + public override void FromXmlString(string xmlString) => _wrapped.FromXmlString(xmlString); + + public override string ToXmlString(bool includePrivateParameters) => + _wrapped.ToXmlString(includePrivateParameters); + + public override RSAParameters ExportParameters(bool includePrivateParameters) => + _wrapped.ExportParameters(includePrivateParameters); + + public override void ImportParameters(RSAParameters parameters) => _wrapped.ImportParameters(parameters); + + public override byte[] Encrypt(byte[] data, RSAEncryptionPadding padding) => _wrapped.Encrypt(data, padding); + + public override byte[] Decrypt(byte[] data, RSAEncryptionPadding padding) => _wrapped.Decrypt(data, padding); + + public override byte[] SignHash( + byte[] hash, + HashAlgorithmName hashAlgorithm, + RSASignaturePadding padding) => + _wrapped.SignHash(hash, hashAlgorithm, padding); + + public override bool VerifyHash( + byte[] hash, + byte[] signature, + HashAlgorithmName hashAlgorithm, + RSASignaturePadding padding) => + _wrapped.VerifyHash(hash, signature, hashAlgorithm, padding); + + public override bool TryDecrypt( + ReadOnlySpan data, + Span destination, + RSAEncryptionPadding padding, + out int bytesWritten) => + _wrapped.TryDecrypt(data, destination, padding, out bytesWritten); + + public override bool TryEncrypt( + ReadOnlySpan data, + Span destination, + RSAEncryptionPadding padding, + out int bytesWritten) => + _wrapped.TryEncrypt(data, destination, padding, out bytesWritten); + + public override bool TrySignHash( + ReadOnlySpan hash, + Span destination, + HashAlgorithmName hashAlgorithm, + RSASignaturePadding padding, + out int bytesWritten) => + _wrapped.TrySignHash(hash, destination, hashAlgorithm, padding, out bytesWritten); + + public override bool VerifyHash( + ReadOnlySpan hash, + ReadOnlySpan signature, + HashAlgorithmName hashAlgorithm, + RSASignaturePadding padding) => + _wrapped.VerifyHash(hash, signature, hashAlgorithm, padding); + + public override byte[] DecryptValue(byte[] rgb) => _wrapped.DecryptValue(rgb); + + public override byte[] EncryptValue(byte[] rgb) => _wrapped.EncryptValue(rgb); + + public override byte[] SignData( + byte[] data, + int offset, + int count, + HashAlgorithmName hashAlgorithm, + RSASignaturePadding padding) => + _wrapped.SignData(data, offset, count, hashAlgorithm, padding); + + public override byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) => + _wrapped.SignData(data, hashAlgorithm, padding); + + public override bool TrySignData( + ReadOnlySpan data, + Span destination, + HashAlgorithmName hashAlgorithm, + RSASignaturePadding padding, + out int bytesWritten) => + _wrapped.TrySignData(data, destination, hashAlgorithm, padding, out bytesWritten); + + public override bool VerifyData( + byte[] data, + int offset, + int count, + byte[] signature, + HashAlgorithmName hashAlgorithm, + RSASignaturePadding padding) => + _wrapped.VerifyData(data, offset, count, signature, hashAlgorithm, padding); + + public override bool VerifyData( + ReadOnlySpan data, + ReadOnlySpan signature, + HashAlgorithmName hashAlgorithm, + RSASignaturePadding padding) => + _wrapped.VerifyData(data, signature, hashAlgorithm, padding); + + public override byte[] ExportRSAPrivateKey() => _wrapped.ExportRSAPrivateKey(); + + public override bool TryExportRSAPrivateKey(Span destination, out int bytesWritten) => + _wrapped.TryExportRSAPrivateKey(destination, out bytesWritten); + + public override byte[] ExportRSAPublicKey() => _wrapped.ExportRSAPublicKey(); + + public override bool TryExportRSAPublicKey(Span destination, out int bytesWritten) => + _wrapped.TryExportRSAPublicKey(destination, out bytesWritten); + + public override bool TryExportSubjectPublicKeyInfo(Span destination, out int bytesWritten) => + _wrapped.TryExportSubjectPublicKeyInfo(destination, out bytesWritten); + + public override bool TryExportPkcs8PrivateKey(Span destination, out int bytesWritten) => + _wrapped.TryExportPkcs8PrivateKey(destination, out bytesWritten); + + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) => + _wrapped.TryExportEncryptedPkcs8PrivateKey(password, pbeParameters, destination, out bytesWritten); + + public override bool TryExportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + PbeParameters pbeParameters, + Span destination, + out int bytesWritten) => + _wrapped.TryExportEncryptedPkcs8PrivateKey(passwordBytes, pbeParameters, destination, out bytesWritten); + + public override void ImportSubjectPublicKeyInfo(ReadOnlySpan source, out int bytesRead) => + _wrapped.ImportSubjectPublicKeyInfo(source, out bytesRead); + + public override void ImportRSAPublicKey(ReadOnlySpan source, out int bytesRead) => + _wrapped.ImportRSAPublicKey(source, out bytesRead); + + public override void ImportRSAPrivateKey(ReadOnlySpan source, out int bytesRead) => + _wrapped.ImportRSAPrivateKey(source, out bytesRead); + + public override void ImportPkcs8PrivateKey(ReadOnlySpan source, out int bytesRead) => + _wrapped.ImportPkcs8PrivateKey(source, out bytesRead); + + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan passwordBytes, + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead); + + public override void ImportEncryptedPkcs8PrivateKey( + ReadOnlySpan password, + ReadOnlySpan source, + out int bytesRead) => + _wrapped.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead); + + public override void ImportFromPem(ReadOnlySpan input) => + _wrapped.ImportFromPem(input); + + public override void ImportFromEncryptedPem(ReadOnlySpan input, ReadOnlySpan password) => + _wrapped.ImportFromEncryptedPem(input, password); + + public override void ImportFromEncryptedPem(ReadOnlySpan input, ReadOnlySpan passwordBytes) => + _wrapped.ImportFromEncryptedPem(input, passwordBytes); + + public override string? KeyExchangeAlgorithm => _wrapped.KeyExchangeAlgorithm; + + public override string SignatureAlgorithm => _wrapped.SignatureAlgorithm; + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _wrapped.Dispose(); + } + + base.Dispose(disposing); + } + + public override bool Equals(object? obj) => _wrapped.Equals(obj); + + public override int GetHashCode() => _wrapped.GetHashCode(); + + public override string ToString() => _wrapped.ToString()!; + } +} diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/SHA1CryptoServiceProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA1CryptoServiceProvider.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/SHA1CryptoServiceProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA1CryptoServiceProvider.cs diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/SHA256CryptoServiceProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA256CryptoServiceProvider.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/SHA256CryptoServiceProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA256CryptoServiceProvider.cs diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/SHA384CryptoServiceProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA384CryptoServiceProvider.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/SHA384CryptoServiceProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA384CryptoServiceProvider.cs diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/SHA512CryptoServiceProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA512CryptoServiceProvider.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/SHA512CryptoServiceProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHA512CryptoServiceProvider.cs diff --git a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SafeEvpPKeyHandle.OpenSsl.cs similarity index 77% rename from src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SafeEvpPKeyHandle.OpenSsl.cs index 9e67a1a9df2d6f..47b6ba4812e541 100644 --- a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SafeEvpPKeyHandle.OpenSsl.cs @@ -3,23 +3,29 @@ using System.Diagnostics; using System.Runtime.InteropServices; +using System.Runtime.Versioning; namespace System.Security.Cryptography { -#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS - internal -#else - public -#endif - sealed class SafeEvpPKeyHandle : SafeHandle + public sealed class SafeEvpPKeyHandle : SafeHandle { internal static readonly SafeEvpPKeyHandle InvalidHandle = new SafeEvpPKeyHandle(); + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public SafeEvpPKeyHandle() : base(IntPtr.Zero, ownsHandle: true) { } + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public SafeEvpPKeyHandle(IntPtr handle, bool ownsHandle) : base(handle, ownsHandle) { @@ -65,7 +71,6 @@ public SafeEvpPKeyHandle DuplicateHandle() return safeHandle; } -#if !INTERNAL_ASYMMETRIC_IMPLEMENTATIONS /// /// The runtime version number for the loaded version of OpenSSL. /// @@ -73,7 +78,11 @@ public SafeEvpPKeyHandle DuplicateHandle() /// For OpenSSL 1.1+ this is the result of OpenSSL_version_num(), /// for OpenSSL 1.0.x this is the result of SSLeay(). /// + [UnsupportedOSPlatform("android")] + [UnsupportedOSPlatform("browser")] + [UnsupportedOSPlatform("ios")] + [UnsupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("windows")] public static long OpenSslVersion { get; } = Interop.OpenSsl.OpenSslVersionNumber(); -#endif } } diff --git a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/TripleDESCng.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDESCng.Windows.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/TripleDESCng.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDESCng.Windows.cs index 710053fa4e5595..808b8902d34ebb 100644 --- a/src/libraries/System.Security.Cryptography.Cng/src/System/Security/Cryptography/TripleDESCng.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDESCng.Windows.cs @@ -8,6 +8,7 @@ // that each of these derive from a different class, it can't be helped. // +using System.Runtime.Versioning; using Internal.Cryptography; using Internal.NativeCrypto; @@ -16,21 +17,25 @@ namespace System.Security.Cryptography [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "We are providing the implementation for TripleDES, not consuming it")] public sealed class TripleDESCng : TripleDES, ICngSymmetricAlgorithm { + [SupportedOSPlatform("windows")] public TripleDESCng() { _core = new CngSymmetricAlgorithmCore(this); } + [SupportedOSPlatform("windows")] public TripleDESCng(string keyName) : this(keyName, CngProvider.MicrosoftSoftwareKeyStorageProvider) { } + [SupportedOSPlatform("windows")] public TripleDESCng(string keyName, CngProvider provider) : this(keyName, provider, CngKeyOpenOptions.None) { } + [SupportedOSPlatform("windows")] public TripleDESCng(string keyName, CngProvider provider, CngKeyOpenOptions openOptions) { _core = new CngSymmetricAlgorithmCore(this, keyName, provider, openOptions); @@ -238,7 +243,7 @@ SafeAlgorithmHandle ICngSymmetricAlgorithm.GetEphemeralModeHandle(CipherMode mod string ICngSymmetricAlgorithm.GetNCryptAlgorithmIdentifier() { - return Interop.NCrypt.NCRYPT_3DES_ALGORITHM; + return Cng.BCRYPT_3DES_ALGORITHM; } byte[] ICngSymmetricAlgorithm.PreprocessKey(byte[] key) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.NotSupported.cs new file mode 100644 index 00000000000000..7de61d03744f57 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.NotSupported.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; + +namespace System.Security.Cryptography +{ + [Obsolete(Obsoletions.DerivedCryptographicTypesMessage, DiagnosticId = Obsoletions.DerivedCryptographicTypesDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class TripleDESCryptoServiceProvider : TripleDES + { + [SuppressMessage("Microsoft.Security", "CA5350", Justification = "This is the implementation of TripleDES")] + public TripleDESCryptoServiceProvider() + { + throw new PlatformNotSupportedException(); + } + + public override void GenerateIV() { } + public override void GenerateKey() { } + public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) => default!; + public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) => default!; + } +} diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.Wrap.cs similarity index 93% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.Wrap.cs index 6e40774f0f855b..156eae13904aed 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.Wrap.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; -using Internal.Cryptography; namespace System.Security.Cryptography { @@ -68,10 +67,10 @@ public override PaddingMode Padding public override void GenerateKey() => _impl.GenerateKey(); public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[]? rgbIV) => - _impl.CreateEncryptor(rgbKey, Helpers.TrimLargeIV(rgbIV, BlockSize)); + _impl.CreateEncryptor(rgbKey, CapiHelper.TrimLargeIV(rgbIV, BlockSize)); public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[]? rgbIV) => - _impl.CreateDecryptor(rgbKey, Helpers.TrimLargeIV(rgbIV, BlockSize)); + _impl.CreateDecryptor(rgbKey, CapiHelper.TrimLargeIV(rgbIV, BlockSize)); protected override void Dispose(bool disposing) { diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/Utils.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Utils.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/Utils.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Utils.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/AndroidCertificatePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AndroidCertificatePal.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/AndroidCertificatePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AndroidCertificatePal.cs index d765cd0b56a4da..87affa5408d585 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/AndroidCertificatePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AndroidCertificatePal.cs @@ -1,20 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Formats.Asn1; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; using System.Text; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class AndroidCertificatePal : ICertificatePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/AndroidPkcs12Reader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AndroidPkcs12Reader.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/AndroidPkcs12Reader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AndroidPkcs12Reader.cs index af679b1342bcc4..a22e15530798f4 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/AndroidPkcs12Reader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AndroidPkcs12Reader.cs @@ -1,16 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Formats.Asn1; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class AndroidPkcs12Reader : UnixPkcs12Reader { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificateExporter.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificateExporter.iOS.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificateExporter.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificateExporter.iOS.cs index 54bf659a1fcca5..542dcf8d36c2a6 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificateExporter.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificateExporter.iOS.cs @@ -1,13 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class AppleCertificateExporter : UnixExportProvider { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.ImportExport.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.ImportExport.iOS.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.ImportExport.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.ImportExport.iOS.cs index dd8fb2ac2ddafd..26fbe98478b54b 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.ImportExport.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.ImportExport.iOS.cs @@ -1,22 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; -using System.Collections.Generic; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; -using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; -using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.Asn1.Pkcs12; using System.Security.Cryptography.Asn1.Pkcs7; -using System.Text; -using System.Threading; +using System.Security.Cryptography.Asn1.Pkcs12; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class AppleCertificatePal : ICertificatePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.ImportExport.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.ImportExport.macOS.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.ImportExport.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.ImportExport.macOS.cs index f6b19f9bb03946..f15d48e8ea61f2 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.ImportExport.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.ImportExport.macOS.cs @@ -1,19 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; -using System.Collections.Generic; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; -using System.Text; using System.Threading; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class AppleCertificatePal : ICertificatePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.Keys.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.iOS.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.Keys.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.iOS.cs index 98a8df28cf255d..9076f0c4899a1b 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.Keys.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.iOS.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Security.Cryptography; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class AppleCertificatePal : ICertificatePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.Keys.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.macOS.cs similarity index 80% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.Keys.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.macOS.cs index 4231c82f0ac958..49107777cd5bad 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.Keys.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Keys.macOS.cs @@ -1,19 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class AppleCertificatePal : ICertificatePal { @@ -57,13 +54,30 @@ public ICertificatePal CopyWithPrivateKey(DSA privateKey) public ICertificatePal CopyWithPrivateKey(ECDsa privateKey) { var typedKey = privateKey as ECDsaImplementation.ECDsaSecurityTransforms; + byte[] ecPrivateKey; if (typedKey != null) { - return CopyWithPrivateKey(typedKey.GetKeys().PrivateKey); + ECParameters ecParameters = default; + + if (typedKey.TryExportDataKeyParameters(includePrivateParameters: true, ref ecParameters)) + { + using (PinAndClear.Track(ecParameters.D!)) + { + AsnWriter writer = EccKeyFormatHelper.WriteECPrivateKey(ecParameters); + ecPrivateKey = writer.Encode(); + writer.Reset(); + } + } + else + { + return CopyWithPrivateKey(typedKey.GetKeys().PrivateKey); + } + } + else + { + ecPrivateKey = privateKey.ExportECPrivateKey(); } - - byte[] ecPrivateKey = privateKey.ExportECPrivateKey(); using (PinAndClear.Track(ecPrivateKey)) using (SafeSecKeyRefHandle privateSecKey = Interop.AppleCrypto.ImportEphemeralKey(ecPrivateKey, true)) @@ -75,13 +89,30 @@ public ICertificatePal CopyWithPrivateKey(ECDsa privateKey) public ICertificatePal CopyWithPrivateKey(ECDiffieHellman privateKey) { var typedKey = privateKey as ECDiffieHellmanImplementation.ECDiffieHellmanSecurityTransforms; + byte[] ecPrivateKey; if (typedKey != null) { - return CopyWithPrivateKey(typedKey.GetKeys().PrivateKey); + ECParameters ecParameters = default; + + if (typedKey.TryExportDataKeyParameters(includePrivateParameters: true, ref ecParameters)) + { + using (PinAndClear.Track(ecParameters.D!)) + { + AsnWriter writer = EccKeyFormatHelper.WriteECPrivateKey(ecParameters); + ecPrivateKey = writer.Encode(); + writer.Reset(); + } + } + else + { + return CopyWithPrivateKey(typedKey.GetKeys().PrivateKey); + } + } + else + { + ecPrivateKey = privateKey.ExportECPrivateKey(); } - - byte[] ecPrivateKey = privateKey.ExportECPrivateKey(); using (PinAndClear.Track(ecPrivateKey)) using (SafeSecKeyRefHandle privateSecKey = Interop.AppleCrypto.ImportEphemeralKey(ecPrivateKey, true)) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.Pem.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Pem.iOS.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.Pem.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Pem.iOS.cs index 73d0e7b2371278..6862508a7845c2 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.Pem.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Pem.iOS.cs @@ -1,15 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; using System.Diagnostics; using System.Text; -using System.Security.Cryptography; -using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; +using Internal.Cryptography; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class AppleCertificatePal : ICertificatePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.Pkcs12.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Pkcs12.iOS.cs similarity index 82% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.Pkcs12.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Pkcs12.iOS.cs index 8ff5988f557d23..01a60958416186 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/AppleCertificatePal.Pkcs12.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Pkcs12.iOS.cs @@ -1,20 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Diagnostics; -using System.Formats.Asn1; -using System.Security.Cryptography; -using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; -using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.Asn1.Pkcs12; -using System.Text; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class AppleCertificatePal : ICertificatePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.Pkcs12.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Pkcs12.macOS.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.Pkcs12.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Pkcs12.macOS.cs index 1eaa3f8323adc0..118f7067691e6f 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.Pkcs12.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.Pkcs12.macOS.cs @@ -1,13 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class AppleCertificatePal : ICertificatePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.TempExportPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.TempExportPal.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.TempExportPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.TempExportPal.cs index 58553f50307b02..035dde20c5f088 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.TempExportPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.TempExportPal.cs @@ -1,13 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class AppleCertificatePal : ICertificatePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.cs index 5334d9eb31a0bf..fb8c18acdcb39e 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/AppleCertificatePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/AppleCertificatePal.cs @@ -1,19 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class AppleCertificatePal : ICertificatePal { @@ -62,11 +60,12 @@ internal sealed partial class AppleCertificatePal : ICertificatePal return null; } - public static ICertificatePal? FromOtherCert(X509Certificate cert) + public static ICertificatePal FromOtherCert(X509Certificate cert) { Debug.Assert(cert.Pal != null); ICertificatePal? pal = FromHandle(cert.Handle); + Debug.Assert(pal != null); GC.KeepAlive(cert); // ensure cert's safe handle isn't finalized while raw handle is in use return pal; } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/ApplePkcs12CertLoader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ApplePkcs12CertLoader.iOS.cs similarity index 84% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/ApplePkcs12CertLoader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ApplePkcs12CertLoader.iOS.cs index 8de11e24f7d80b..c190f3400b9590 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/ApplePkcs12CertLoader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ApplePkcs12CertLoader.iOS.cs @@ -1,15 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; -using System.Security.Cryptography; -using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using System.Threading; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class ApplePkcs12CertLoader : ILoaderPal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/ApplePkcs12Reader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ApplePkcs12Reader.iOS.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/ApplePkcs12Reader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ApplePkcs12Reader.iOS.cs index bb7acb4e27d9c6..5900a979ed83c7 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/ApplePkcs12Reader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ApplePkcs12Reader.iOS.cs @@ -1,16 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; -using System.Security.Cryptography.Apple; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class ApplePkcs12Reader : UnixPkcs12Reader { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/ApplePkcs12Reader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ApplePkcs12Reader.macOS.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/ApplePkcs12Reader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ApplePkcs12Reader.macOS.cs index 6820eec7b9d0b2..7c1121a6c86ac1 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/ApplePkcs12Reader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ApplePkcs12Reader.macOS.cs @@ -1,16 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class ApplePkcs12Reader : UnixPkcs12Reader { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/AccessDescriptionAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/AccessDescriptionAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/AccessDescriptionAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/AccessDescriptionAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/AccessDescriptionAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/AccessDescriptionAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/AccessDescriptionAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/AccessDescriptionAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/BasicConstraintsAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/BasicConstraintsAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/BasicConstraintsAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/BasicConstraintsAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/BasicConstraintsAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/BasicConstraintsAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/BasicConstraintsAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/BasicConstraintsAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificatePolicyMappingAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificatePolicyMappingAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificatePolicyMappingAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificatePolicyMappingAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificatePolicyMappingAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificatePolicyMappingAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificatePolicyMappingAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificatePolicyMappingAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateTemplateAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateTemplateAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateTemplateAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateTemplateAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateTemplateAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateTemplateAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateTemplateAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificateTemplateAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/KeyUsageFlagsAsn.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/KeyUsageFlagsAsn.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/KeyUsageFlagsAsn.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/KeyUsageFlagsAsn.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyConstraintsAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyConstraintsAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyConstraintsAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyConstraintsAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyConstraintsAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyConstraintsAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyConstraintsAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyConstraintsAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyInformationAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyInformationAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyInformationAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyInformationAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyInformationAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyInformationAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyInformationAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/PolicyInformationAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/ReasonFlagsAsn.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/ReasonFlagsAsn.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/ReasonFlagsAsn.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/ReasonFlagsAsn.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.manual.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.manual.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.manual.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.manual.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TbsCertificateAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.manual.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.manual.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.manual.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.manual.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.manual.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.manual.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.manual.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.manual.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.xml b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.xml similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.xml rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.xml diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.xml.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.xml.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/ValidityAsn.xml.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertCollectionLoader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertCollectionLoader.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertCollectionLoader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertCollectionLoader.cs index 96e7477f0baa83..d4c802217fc293 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertCollectionLoader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertCollectionLoader.cs @@ -3,10 +3,10 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Security.Cryptography.X509Certificates; using System.Threading; +using Internal.Cryptography; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class CertCollectionLoader : ILoaderPal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateData.ManagedDecode.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateData.ManagedDecode.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateData.ManagedDecode.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateData.ManagedDecode.cs index af1935e78dc427..0fffcd29701a6e 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateData.ManagedDecode.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateData.ManagedDecode.cs @@ -1,17 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates.Asn1; using System.Text; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal enum GeneralNameType { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/CertificateExtensionsCommon.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateExtensionsCommon.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/CertificateExtensionsCommon.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateExtensionsCommon.cs index 78a34ac1d86c93..1476cea2d57f47 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/CertificateExtensionsCommon.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateExtensionsCommon.cs @@ -1,13 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal static class CertificateExtensionsCommon { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Android.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Android.cs new file mode 100644 index 00000000000000..b11b726037ecde --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Android.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class CertificatePal + { + internal static partial ICertificatePal FromHandle(IntPtr handle) + { + return AndroidCertificatePal.FromHandle(handle); + } + + internal static partial ICertificatePal FromOtherCert(X509Certificate copyFrom) + { + return AndroidCertificatePal.FromOtherCert(copyFrom); + } + + internal static partial ICertificatePal FromBlob( + ReadOnlySpan rawData, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags) + { + return AndroidCertificatePal.FromBlob(rawData, password, keyStorageFlags); + } + + internal static partial ICertificatePal FromFile( + string fileName, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags) + { + return AndroidCertificatePal.FromFile(fileName, password, keyStorageFlags); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Apple.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Apple.cs new file mode 100644 index 00000000000000..79ecb6e1586dc3 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Apple.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class CertificatePal + { + internal static partial ICertificatePal FromHandle(IntPtr handle) + { + return AppleCertificatePal.FromHandle(handle, true)!; + } + + internal static partial ICertificatePal FromOtherCert(X509Certificate copyFrom) + { + return AppleCertificatePal.FromOtherCert(copyFrom); + } + + internal static partial ICertificatePal FromBlob( + ReadOnlySpan rawData, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags) + { + return AppleCertificatePal.FromBlob(rawData, password, keyStorageFlags); + } + + internal static partial ICertificatePal FromFile( + string fileName, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags) + { + return AppleCertificatePal.FromFile(fileName, password, keyStorageFlags); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.NotSupported.cs new file mode 100644 index 00000000000000..eb782130613cf3 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.NotSupported.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class CertificatePal + { + internal static partial ICertificatePal FromHandle(IntPtr handle) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial ICertificatePal FromOtherCert(X509Certificate copyFrom) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial ICertificatePal FromBlob( + ReadOnlySpan rawData, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial ICertificatePal FromFile( + string fileName, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.OpenSsl.cs new file mode 100644 index 00000000000000..7cec9a343b4e9e --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.OpenSsl.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Security.Cryptography; +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class CertificatePal + { + internal static partial ICertificatePal FromHandle(IntPtr handle) + { + return OpenSslX509CertificateReader.FromHandle(handle); + } + + internal static partial ICertificatePal FromOtherCert(X509Certificate copyFrom) + { + return OpenSslX509CertificateReader.FromOtherCert(copyFrom); + } + + internal static partial ICertificatePal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + { + return OpenSslX509CertificateReader.FromBlob(rawData, password, keyStorageFlags); + } + + internal static partial ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + { + return OpenSslX509CertificateReader.FromFile(fileName, password, keyStorageFlags); + } + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.Import.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.Import.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.Import.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.Import.cs index d9c2d1364c45c2..c3d082cec1577d 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.Import.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.Import.cs @@ -1,26 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; -using System; using System.IO; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; - -using Internal.Cryptography.Pal.Native; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed partial class CertificatePal : IDisposable, ICertificatePal + internal sealed partial class CertificatePal { - public static ICertificatePal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ICertificatePal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return FromBlobOrFile(rawData, null, password, keyStorageFlags); } - public static ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ICertificatePal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return FromBlobOrFile(ReadOnlySpan.Empty, fileName, password, keyStorageFlags); } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.PrivateKey.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.PrivateKey.cs index 264079d50d9d13..a93817fac81cdd 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.PrivateKey.cs @@ -1,16 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; -using Internal.Cryptography.Pal.Native; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class CertificatePal : IDisposable, ICertificatePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs index a6fc4c8e57a90b..244e151372c07f 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs @@ -1,26 +1,23 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; -using System; using System.Text; using System.Diagnostics; using System.Collections.Generic; using System.Runtime.InteropServices; -using Internal.Cryptography.Pal.Native; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; -using System.Security.Cryptography; using SafeX509ChainHandle = Microsoft.Win32.SafeHandles.SafeX509ChainHandle; using SafePasswordHandle = Microsoft.Win32.SafeHandles.SafePasswordHandle; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class CertificatePal : IDisposable, ICertificatePal { private SafeCertContextHandle _certContext; - public static ICertificatePal FromHandle(IntPtr handle) + internal static partial ICertificatePal FromHandle(IntPtr handle) { if (handle == IntPtr.Zero) throw new ArgumentException(SR.Arg_InvalidHandle, nameof(handle)); @@ -39,7 +36,7 @@ public static ICertificatePal FromHandle(IntPtr handle) /// creating another X509Certificate object based on this one to ensure the underlying /// cert context is not released at the wrong time. /// - public static ICertificatePal FromOtherCert(X509Certificate copyFrom) + internal static partial ICertificatePal FromOtherCert(X509Certificate copyFrom) { CertificatePal pal = new CertificatePal((CertificatePal)copyFrom.Pal!); return pal; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.cs new file mode 100644 index 00000000000000..5703ec35dd47bc --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.X509Certificates +{ + internal partial class CertificatePal + { + internal static partial ICertificatePal FromHandle(IntPtr handle); + + internal static partial ICertificatePal FromOtherCert(X509Certificate copyFrom); + + internal static partial ICertificatePal FromBlob( + ReadOnlySpan rawData, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags); + + internal static partial ICertificatePal FromFile( + string fileName, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags); + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePolicy.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePolicy.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePolicy.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePolicy.cs index 5d3fe08cbfc761..22430e72cb5eaa 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePolicy.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePolicy.cs @@ -1,14 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Formats.Asn1; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates.Asn1; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class CertificatePolicy { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs index 2417cacbc7a4fc..02061235b3935f 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificateRequest.cs @@ -5,6 +5,7 @@ using System.Collections.ObjectModel; using System.Diagnostics; using System.Formats.Asn1; +using System.Runtime.Versioning; using System.Security.Cryptography.Asn1; using System.Security.Cryptography.X509Certificates.Asn1; using Internal.Cryptography; @@ -16,6 +17,7 @@ namespace System.Security.Cryptography.X509Certificates /// allowing callers to create self-signed or chain-signed X.509 Public-Key Certificates, as well as /// create a certificate signing request blob to send to a Certificate Authority (CA). /// + [UnsupportedOSPlatform("browser")] public sealed class CertificateRequest { private readonly AsymmetricAlgorithm? _key; @@ -612,7 +614,7 @@ public X509Certificate2 Create( signatureAlgorithmAsn = AlgorithmIdentifierAsn.Decode(signatureAlgorithm, AsnEncodingRules.DER); if (signatureAlgorithmAsn.Parameters.HasValue) { - Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value); + Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value.Span); } ArraySegment normalizedSerial = NormalizeSerialNumber(serialNumber); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/ChainPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Android.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/ChainPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Android.cs index 1af847e0defe97..3096f31fed0051 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/ChainPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Android.cs @@ -6,33 +6,32 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; - +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class ChainPal { - public static IChainPal FromHandle(IntPtr chainContext) + internal static partial IChainPal FromHandle(IntPtr chainContext) { throw new PlatformNotSupportedException(); } - public static bool ReleaseSafeX509ChainHandle(IntPtr handle) + internal static partial bool ReleaseSafeX509ChainHandle(IntPtr handle) { return true; } - public static IChainPal BuildChain( + internal static partial IChainPal? BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection? extraStore, - OidCollection applicationPolicy, - OidCollection certificatePolicy, + OidCollection? applicationPolicy, + OidCollection? certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, - X509Certificate2Collection customTrustStore, + X509Certificate2Collection? customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, @@ -86,13 +85,13 @@ public void Dispose() return false; } - return ChainVerifier.Verify(ChainElements!, flags); + return UnixChainVerifier.Verify(ChainElements!, flags); } internal void Initialize( ICertificatePal cert, X509Certificate2Collection? extraStore, - X509Certificate2Collection customTrustStore, + X509Certificate2Collection? customTrustStore, X509ChainTrustMode trustMode) { List extraCertHandles = new List() { ((AndroidCertificatePal)cert).SafeHandle }; @@ -186,8 +185,8 @@ internal void Initialize( internal void Evaluate( DateTime verificationTime, - OidCollection applicationPolicy, - OidCollection certificatePolicy, + OidCollection? applicationPolicy, + OidCollection? certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag) { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/ChainPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Apple.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/ChainPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Apple.cs index 2a26d06f80580b..81e9b3678b5403 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/ChainPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Apple.cs @@ -1,15 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class SecTrustChainPal : IChainPal { @@ -37,7 +35,7 @@ internal void OpenTrustHandle( ICertificatePal leafCert, X509Certificate2Collection? extraStore, X509RevocationMode revocationMode, - X509Certificate2Collection customTrustStore, + X509Certificate2Collection? customTrustStore, X509ChainTrustMode trustMode) { _revocationMode = revocationMode; @@ -115,7 +113,7 @@ public void Dispose() { exception = null; - return ChainVerifier.Verify(ChainElements!, flags); + return UnixChainVerifier.Verify(ChainElements!, flags); } private SafeCreateHandle PreparePoliciesArray(bool checkRevocation) @@ -150,7 +148,7 @@ private SafeCreateHandle PreparePoliciesArray(bool checkRevocation) private SafeCreateHandle PrepareCertsArray( ICertificatePal cert, X509Certificate2Collection? extraStore, - X509Certificate2Collection customTrustStore, + X509Certificate2Collection? customTrustStore, X509ChainTrustMode trustMode) { List safeHandles = new List { ((AppleCertificatePal)cert).CertificateHandle }; @@ -227,8 +225,8 @@ private SafeCreateHandle GetCertsArray(IList safeHandles) internal void Execute( DateTime verificationTime, bool allowNetwork, - OidCollection applicationPolicy, - OidCollection certificatePolicy, + OidCollection? applicationPolicy, + OidCollection? certificatePolicy, X509RevocationFlag revocationFlag) { int osStatus; @@ -310,8 +308,8 @@ private static (X509Certificate2, int)[] ParseResults( private bool IsPolicyMatch( (X509Certificate2, int)[] elements, - OidCollection applicationPolicy, - OidCollection certificatePolicy) + OidCollection? applicationPolicy, + OidCollection? certificatePolicy) { if (applicationPolicy?.Count > 0 || certificatePolicy?.Count > 0) { @@ -551,7 +549,7 @@ private X509ChainErrorMapping(X509ChainStatusFlags flag) internal sealed partial class ChainPal { - public static IChainPal FromHandle(IntPtr chainContext) + internal static partial IChainPal FromHandle(IntPtr chainContext) { // This is possible to do on Apple's platform, but is tricky in execution. // In Windows, CertGetCertificateChain is what allocates the handle, and it does @@ -581,21 +579,21 @@ public static IChainPal FromHandle(IntPtr chainContext) throw new PlatformNotSupportedException(); } - public static bool ReleaseSafeX509ChainHandle(IntPtr handle) + internal static partial bool ReleaseSafeX509ChainHandle(IntPtr handle) { Interop.CoreFoundation.CFRelease(handle); return true; } - public static IChainPal BuildChain( + internal static partial IChainPal? BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection? extraStore, - OidCollection applicationPolicy, - OidCollection certificatePolicy, + OidCollection? applicationPolicy, + OidCollection? certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, - X509Certificate2Collection customTrustStore, + X509Certificate2Collection? customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.NotSupported.cs new file mode 100644 index 00000000000000..fd6bf95e4baa35 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.NotSupported.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class ChainPal + { + internal static partial IChainPal FromHandle(IntPtr chainContext) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial bool ReleaseSafeX509ChainHandle(IntPtr handle) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial IChainPal? BuildChain( + bool useMachineContext, + ICertificatePal cert, + X509Certificate2Collection? extraStore, + OidCollection? applicationPolicy, + OidCollection? certificatePolicy, + X509RevocationMode revocationMode, + X509RevocationFlag revocationFlag, + X509Certificate2Collection? customTrustStore, + X509ChainTrustMode trustMode, + DateTime verificationTime, + TimeSpan timeout, + bool disableAia) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.OpenSsl.cs similarity index 91% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.OpenSsl.cs index 29cdfa5f71cb72..fa6db427ac7522 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.OpenSsl.cs @@ -1,24 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class ChainPal { private static readonly TimeSpan s_maxUrlRetrievalTimeout = TimeSpan.FromMinutes(1); - public static IChainPal FromHandle(IntPtr chainContext) + internal static partial IChainPal FromHandle(IntPtr chainContext) { throw new PlatformNotSupportedException(); } - public static bool ReleaseSafeX509ChainHandle(IntPtr handle) + internal static partial bool ReleaseSafeX509ChainHandle(IntPtr handle) { return true; } @@ -28,15 +25,15 @@ public static void FlushStores() OpenSslX509ChainProcessor.FlushStores(); } - public static IChainPal BuildChain( + internal static partial IChainPal? BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection? extraStore, - OidCollection applicationPolicy, - OidCollection certificatePolicy, + OidCollection? applicationPolicy, + OidCollection? certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, - X509Certificate2Collection customTrustStore, + X509Certificate2Collection? customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout, diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.BuildChain.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.BuildChain.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.BuildChain.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.BuildChain.cs index ce38255742da7c..e1fee5d3137663 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.BuildChain.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.BuildChain.cs @@ -1,25 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; -using System; using System.Runtime.InteropServices; - -using Internal.Cryptography.Pal.Native; - -using System.Security.Cryptography; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; using SafeX509ChainHandle = Microsoft.Win32.SafeHandles.SafeX509ChainHandle; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class ChainPal : IDisposable, IChainPal { /// /// Does not throw on error. Returns null ChainPal instead. /// - public static ChainPal? BuildChain( + internal static partial IChainPal? BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection? extraStore, @@ -138,10 +133,5 @@ private static Interop.Crypt32.CertChainFlags MapRevocationFlags( return dwFlags; } - - private ChainPal(SafeX509ChainHandle chain) - { - _chain = chain; - } } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.GetChainStatusInformation.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.GetChainStatusInformation.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.GetChainStatusInformation.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.GetChainStatusInformation.cs index cd5b60e21dd255..e22f6c8adb49a2 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.GetChainStatusInformation.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.GetChainStatusInformation.cs @@ -1,14 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Text; using System.Diagnostics; -using System.Security.Cryptography.X509Certificates; -using Internal.Cryptography.Pal.Native; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class ChainPal : IDisposable, IChainPal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.cs index 5b80a71eb8c487..53006b879413bd 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.cs @@ -1,20 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography.Pal.Native; -using Microsoft.Win32.SafeHandles; -using System; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class ChainPal : IDisposable, IChainPal { private SafeX509ChainHandle _chain; - public static IChainPal FromHandle(IntPtr chainContext) + private ChainPal(SafeX509ChainHandle chain) + { + _chain = chain; + } + + internal static partial IChainPal FromHandle(IntPtr chainContext) { if (chainContext == IntPtr.Zero) throw new ArgumentNullException(nameof(chainContext)); @@ -103,7 +105,7 @@ public SafeX509ChainHandle SafeHandle } } - public static bool ReleaseSafeX509ChainHandle(IntPtr handle) + internal static partial bool ReleaseSafeX509ChainHandle(IntPtr handle) { Interop.Crypt32.CertFreeCertificateChain(handle); return true; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.cs new file mode 100644 index 00000000000000..2d765b6f8158de --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.X509Certificates +{ + internal partial class ChainPal + { + internal static partial IChainPal FromHandle(IntPtr chainContext); + + internal static partial bool ReleaseSafeX509ChainHandle(IntPtr handle); + + internal static partial IChainPal? BuildChain( + bool useMachineContext, + ICertificatePal cert, + X509Certificate2Collection? extraStore, + OidCollection? applicationPolicy, + OidCollection? certificatePolicy, + X509RevocationMode revocationMode, + X509RevocationFlag revocationFlag, + X509Certificate2Collection? customTrustStore, + X509ChainTrustMode trustMode, + DateTime verificationTime, + TimeSpan timeout, + bool disableAia); + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/DSACertificateExtensions.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/DSACertificateExtensions.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/DSACertificateExtensions.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/DSACertificateExtensions.cs index c234da08473160..ac63e7062228d0 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/DSACertificateExtensions.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/DSACertificateExtensions.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography; -using Internal.Cryptography.Pal; using System.Runtime.Versioning; namespace System.Security.Cryptography.X509Certificates diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/ECDsaCertificateExtensions.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ECDsaCertificateExtensions.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/ECDsaCertificateExtensions.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ECDsaCertificateExtensions.cs index 4ba58e63590e32..8694dc25423a26 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/ECDsaCertificateExtensions.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ECDsaCertificateExtensions.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using Internal.Cryptography; -using Internal.Cryptography.Pal; namespace System.Security.Cryptography.X509Certificates { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/ECDsaX509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ECDsaX509SignatureGenerator.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/ECDsaX509SignatureGenerator.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ECDsaX509SignatureGenerator.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ErrorCode.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ErrorCode.cs similarity index 83% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ErrorCode.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ErrorCode.cs index a309d5963e3a83..06973a4da75bf9 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ErrorCode.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ErrorCode.cs @@ -1,19 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Text; -using System.Diagnostics; -using System.Globalization; -using System.Security.Cryptography; - -namespace Internal.Cryptography +namespace System.Security.Cryptography.X509Certificates { + // Error codes for specific throw sites. // - // Error codes for specific throw sites. Defined outside of Internal.Crytography.Pal.Native as some non-Pal code uses these. - // Since these error codes are publicly surfaced through the Exception class, these hresults are effectively managed exchange values despite + // Since these error codes are publicly surfaced through the Exception class, + // these HResults are effectively managed exchange values despite // their Win32 origin. - // internal static class ErrorCode { public const int CERT_E_CHAINING = unchecked((int)0x800B010A); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/FindPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Android.cs similarity index 79% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/FindPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Android.cs index 6775a18d5626c6..c7fb948ee82ae1 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/FindPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Android.cs @@ -1,15 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class FindPal { - internal static IFindPal OpenPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) + private static partial IFindPal OpenPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) { return new AndroidCertificateFinder(findFrom, copyTo, validOnly); } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/FindPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Apple.cs similarity index 81% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/FindPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Apple.cs index 645d2bd398c2db..8060d6d9a01da7 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/FindPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Apple.cs @@ -1,15 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class FindPal { - internal static IFindPal OpenPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) + private static partial IFindPal OpenPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) { return new AppleCertificateFinder(findFrom, copyTo, validOnly); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.NotSupported.cs new file mode 100644 index 00000000000000..0c3dd97f84219f --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.NotSupported.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class FindPal + { + private static partial IFindPal OpenPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.OpenSsl.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.OpenSsl.cs new file mode 100644 index 00000000000000..d7a6a64acec6cb --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.OpenSsl.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics; +using System.Numerics; +using Internal.Cryptography; + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class FindPal + { + private static partial IFindPal OpenPal( + X509Certificate2Collection findFrom, + X509Certificate2Collection copyTo, + bool validOnly) + { + return new OpenSslCertificateFinder(findFrom, copyTo, validOnly); + } + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/FindPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Windows.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/FindPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Windows.cs index 4cadc49aaf2c67..8d02c46c3f52ae 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/FindPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Windows.cs @@ -1,16 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Numerics; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -using Internal.Cryptography.Pal.Native; +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class FindPal : IFindPal { @@ -18,14 +15,14 @@ internal sealed partial class FindPal : IFindPal private readonly X509Certificate2Collection _copyTo; private readonly bool _validOnly; - internal FindPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) + private FindPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) { _storePal = (StorePal)StorePal.LinkFromCertificateCollection(findFrom); _copyTo = copyTo; _validOnly = validOnly; } - internal static IFindPal OpenPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) + private static partial IFindPal OpenPal(X509Certificate2Collection findFrom, X509Certificate2Collection copyTo, bool validOnly) { return new FindPal(findFrom, copyTo, validOnly); } @@ -369,7 +366,7 @@ private static bool VerifyCertificateIgnoringErrors(SafeCertContextHandle pCertC { // This needs to be kept in sync with IsCertValid in the // Unix/OpenSSL PAL version (and potentially any other PALs that come about) - ChainPal? chainPal = ChainPal.BuildChain( + ChainPal? chainPal = (ChainPal?)ChainPal.BuildChain( false, CertificatePal.FromHandle(pCertContext.DangerousGetHandle()), extraStore: null, diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/FindPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.cs similarity index 60% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/FindPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.cs index 0cdbbe6555ebe6..d62a967df7959c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/FindPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.cs @@ -1,16 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Numerics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; +using Internal.Cryptography; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed partial class FindPal + internal partial class FindPal { private const int NamedKeyUsageFlagsCount = 9; @@ -35,6 +33,11 @@ static FindPal() } #endif + private static partial IFindPal OpenPal( + X509Certificate2Collection findFrom, + X509Certificate2Collection copyTo, + bool validOnly); + public static X509Certificate2Collection FindFromCollection( X509Certificate2Collection coll, X509FindType findType, @@ -48,107 +51,107 @@ public static X509Certificate2Collection FindFromCollection( switch (findType) { case X509FindType.FindByThumbprint: - { - byte[] thumbPrint = ConfirmedCast(findValue).DecodeHexString(); - findPal.FindByThumbprint(thumbPrint); - break; - } + { + byte[] thumbPrint = ConfirmedCast(findValue).LaxDecodeHexString(); + findPal.FindByThumbprint(thumbPrint); + break; + } case X509FindType.FindBySubjectName: - { - string subjectName = ConfirmedCast(findValue); - findPal.FindBySubjectName(subjectName); - break; - } + { + string subjectName = ConfirmedCast(findValue); + findPal.FindBySubjectName(subjectName); + break; + } case X509FindType.FindBySubjectDistinguishedName: - { - string subjectDistinguishedName = ConfirmedCast(findValue); - findPal.FindBySubjectDistinguishedName(subjectDistinguishedName); - break; - } + { + string subjectDistinguishedName = ConfirmedCast(findValue); + findPal.FindBySubjectDistinguishedName(subjectDistinguishedName); + break; + } case X509FindType.FindByIssuerName: - { - string issuerName = ConfirmedCast(findValue); - findPal.FindByIssuerName(issuerName); - break; - } + { + string issuerName = ConfirmedCast(findValue); + findPal.FindByIssuerName(issuerName); + break; + } case X509FindType.FindByIssuerDistinguishedName: - { - string issuerDistinguishedName = ConfirmedCast(findValue); - findPal.FindByIssuerDistinguishedName(issuerDistinguishedName); - break; - } + { + string issuerDistinguishedName = ConfirmedCast(findValue); + findPal.FindByIssuerDistinguishedName(issuerDistinguishedName); + break; + } case X509FindType.FindBySerialNumber: - { - string decimalOrHexString = ConfirmedCast(findValue); - - // FindBySerialNumber allows the input format to be either in - // hex or decimal. Since we can't know which one was intended, - // it compares against both interpretations and treats a match - // of either as a successful find. - - // string is big-endian, BigInteger constructor requires little-endian. - byte[] hexBytes = decimalOrHexString.DecodeHexString(); - Array.Reverse(hexBytes); - - BigInteger hexValue = PositiveBigIntegerFromByteArray(hexBytes); - BigInteger decimalValue = LaxParseDecimalBigInteger(decimalOrHexString); - findPal.FindBySerialNumber(hexValue, decimalValue); - break; - } + { + string decimalOrHexString = ConfirmedCast(findValue); + + // FindBySerialNumber allows the input format to be either in + // hex or decimal. Since we can't know which one was intended, + // it compares against both interpretations and treats a match + // of either as a successful find. + + // string is big-endian, BigInteger constructor requires little-endian. + byte[] hexBytes = decimalOrHexString.LaxDecodeHexString(); + Array.Reverse(hexBytes); + + BigInteger hexValue = PositiveBigIntegerFromByteArray(hexBytes); + BigInteger decimalValue = LaxParseDecimalBigInteger(decimalOrHexString); + findPal.FindBySerialNumber(hexValue, decimalValue); + break; + } case X509FindType.FindByTimeValid: - { - DateTime dateTime = ConfirmedCast(findValue); - findPal.FindByTimeValid(dateTime); - break; - } + { + DateTime dateTime = ConfirmedCast(findValue); + findPal.FindByTimeValid(dateTime); + break; + } case X509FindType.FindByTimeNotYetValid: - { - DateTime dateTime = ConfirmedCast(findValue); - findPal.FindByTimeNotYetValid(dateTime); - break; - } + { + DateTime dateTime = ConfirmedCast(findValue); + findPal.FindByTimeNotYetValid(dateTime); + break; + } case X509FindType.FindByTimeExpired: - { - DateTime dateTime = ConfirmedCast(findValue); - findPal.FindByTimeExpired(dateTime); - break; - } + { + DateTime dateTime = ConfirmedCast(findValue); + findPal.FindByTimeExpired(dateTime); + break; + } case X509FindType.FindByTemplateName: - { - string expected = ConfirmedCast(findValue); - findPal.FindByTemplateName(expected); - break; - } + { + string expected = ConfirmedCast(findValue); + findPal.FindByTemplateName(expected); + break; + } case X509FindType.FindByApplicationPolicy: - { - string oidValue = ConfirmedOidValue(findPal, findValue, OidGroup.Policy); - findPal.FindByApplicationPolicy(oidValue); - break; - } + { + string oidValue = ConfirmedOidValue(findPal, findValue, OidGroup.Policy); + findPal.FindByApplicationPolicy(oidValue); + break; + } case X509FindType.FindByCertificatePolicy: - { - string oidValue = ConfirmedOidValue(findPal, findValue, OidGroup.Policy); - findPal.FindByCertificatePolicy(oidValue); - break; - } + { + string oidValue = ConfirmedOidValue(findPal, findValue, OidGroup.Policy); + findPal.FindByCertificatePolicy(oidValue); + break; + } case X509FindType.FindByExtension: - { - string oidValue = ConfirmedOidValue(findPal, findValue, OidGroup.ExtensionOrAttribute); - findPal.FindByExtension(oidValue); - break; - } + { + string oidValue = ConfirmedOidValue(findPal, findValue, OidGroup.ExtensionOrAttribute); + findPal.FindByExtension(oidValue); + break; + } case X509FindType.FindByKeyUsage: - { - X509KeyUsageFlags keyUsage = ConfirmedX509KeyUsage(findValue); - findPal.FindByKeyUsage(keyUsage); - break; - } + { + X509KeyUsageFlags keyUsage = ConfirmedX509KeyUsage(findValue); + findPal.FindByKeyUsage(keyUsage); + break; + } case X509FindType.FindBySubjectKeyIdentifier: - { - byte[] keyIdentifier = ConfirmedCast(findValue).DecodeHexString(); - findPal.FindBySubjectKeyIdentifier(keyIdentifier); - break; - } + { + byte[] keyIdentifier = ConfirmedCast(findValue).LaxDecodeHexString(); + findPal.FindBySubjectKeyIdentifier(keyIdentifier); + break; + } default: throw new CryptographicException(SR.Cryptography_X509_InvalidFindType); } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ICertificatePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ICertificatePal.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ICertificatePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ICertificatePal.cs index d32ddcef440b20..931e5b17618eca 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ICertificatePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ICertificatePal.cs @@ -1,14 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Text; -namespace Internal.Cryptography +namespace System.Security.Cryptography.X509Certificates { [StructLayout(LayoutKind.Sequential)] internal struct PolicyData diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ICertificatePalCore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ICertificatePalCore.cs similarity index 83% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ICertificatePalCore.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ICertificatePalCore.cs index 6a8fa71d233431..6103cae1917634 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ICertificatePalCore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ICertificatePalCore.cs @@ -1,14 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -using System.Text; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography +namespace System.Security.Cryptography.X509Certificates { /// Provides specific implementation for X509Certificate. internal interface ICertificatePalCore : IDisposable diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IChainPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IChainPal.cs similarity index 80% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IChainPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IChainPal.cs index 576d095671f017..797c071f7e7caa 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IChainPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IChainPal.cs @@ -1,13 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Diagnostics.CodeAnalysis; -using System.Security.Cryptography.X509Certificates; - using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal interface IChainPal : IDisposable { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IExportPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IExportPal.cs similarity index 75% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IExportPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IExportPal.cs index 1c5748310eb5d5..36937ea17690cf 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IExportPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IExportPal.cs @@ -2,10 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Win32.SafeHandles; -using System; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal interface IExportPal : IDisposable { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IFindPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IFindPal.cs similarity index 89% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IFindPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IFindPal.cs index 93ea832597f742..13173cd06e5585 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IFindPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IFindPal.cs @@ -1,12 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Numerics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal interface IFindPal : IDisposable { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ILoaderPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ILoaderPal.cs similarity index 71% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ILoaderPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ILoaderPal.cs index 95bb7259062c10..47d3cb84359035 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ILoaderPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ILoaderPal.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Security.Cryptography.X509Certificates; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal interface ILoaderPal : IDisposable { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IStorePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IStorePal.cs similarity index 80% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IStorePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IStorePal.cs index 82faad45710e2d..a785607792ea96 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IStorePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IStorePal.cs @@ -1,11 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Runtime.InteropServices; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal interface IStorePal : IDisposable { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IX509Pal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IX509Pal.cs similarity index 93% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IX509Pal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IX509Pal.cs index dcc3150a35ef86..d83470c3ea1ae6 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IX509Pal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/IX509Pal.cs @@ -1,11 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal interface IX509Pal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ManagedCertificateFinder.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedCertificateFinder.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ManagedCertificateFinder.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedCertificateFinder.cs index e174a9fd593665..d56db1a0c2611b 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ManagedCertificateFinder.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedCertificateFinder.cs @@ -1,16 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Formats.Asn1; using System.Numerics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates.Asn1; +using Internal.Cryptography; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal abstract class ManagedCertificateFinder : IFindPal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ManagedX509ExtensionProcessor.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedX509ExtensionProcessor.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ManagedX509ExtensionProcessor.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedX509ExtensionProcessor.cs index 976021ff7a748e..1749598a6f5472 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ManagedX509ExtensionProcessor.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedX509ExtensionProcessor.cs @@ -1,15 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates.Asn1; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal class ManagedX509ExtensionProcessor { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/OpenFlags.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenFlags.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/OpenFlags.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenFlags.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CachedDirectoryStoreProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedDirectoryStoreProvider.cs similarity index 91% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CachedDirectoryStoreProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedDirectoryStoreProvider.cs index 8c3727b98289d4..da0fc5dff15808 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CachedDirectoryStoreProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedDirectoryStoreProvider.cs @@ -1,14 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.IO; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed class CachedDirectoryStoreProvider + internal sealed class OpenSslCachedDirectoryStoreProvider { // These intervals are mostly arbitrary. // Prior to this caching these stores were always read "hot" from disk, and 30 seconds @@ -24,9 +23,9 @@ internal sealed class CachedDirectoryStoreProvider private DateTime _loadLastWrite; private bool _forceRefresh; - internal CachedDirectoryStoreProvider(string storeName) + internal OpenSslCachedDirectoryStoreProvider(string storeName) { - string storePath = DirectoryBasedStoreProvider.GetStorePath(storeName); + string storePath = OpenSslDirectoryBasedStoreProvider.GetStorePath(storeName); _storeDirectoryInfo = new DirectoryInfo(storePath); } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CachedSystemStoreProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedSystemStoreProvider.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CachedSystemStoreProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedSystemStoreProvider.cs index b6a9ea5505c165..4c9643c01e2fcb 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CachedSystemStoreProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCachedSystemStoreProvider.cs @@ -1,18 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -using System.Security.Cryptography.X509Certificates; using System.Threading; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed class CachedSystemStoreProvider : IStorePal + internal sealed class OpenSslCachedSystemStoreProvider : IStorePal { // These intervals are mostly arbitrary. // Prior to this refreshing cache the system collections were read just once per process, on the @@ -34,16 +32,16 @@ internal sealed class CachedSystemStoreProvider : IStorePal private readonly bool _isRoot; - private CachedSystemStoreProvider(bool isRoot) + private OpenSslCachedSystemStoreProvider(bool isRoot) { _isRoot = isRoot; } - internal static CachedSystemStoreProvider MachineRoot { get; } = - new CachedSystemStoreProvider(true); + internal static OpenSslCachedSystemStoreProvider MachineRoot { get; } = + new OpenSslCachedSystemStoreProvider(true); - internal static CachedSystemStoreProvider MachineIntermediate { get; } = - new CachedSystemStoreProvider(false); + internal static OpenSslCachedSystemStoreProvider MachineIntermediate { get; } = + new OpenSslCachedSystemStoreProvider(false); public void Dispose() diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCertificateAssetDownloader.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCertificateAssetDownloader.cs index cd7ef4b84858a5..1c5656ac5b4624 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCertificateAssetDownloader.cs @@ -1,19 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Threading; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal static class CertificateAssetDownloader + internal static class OpenSslCertificateAssetDownloader { private static readonly Func? s_downloadBytes = CreateDownloadBytesFunc(); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslCertificateFinder.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCertificateFinder.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslCertificateFinder.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCertificateFinder.cs index 8c6d167fdba9d7..03566b40a492c4 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslCertificateFinder.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCertificateFinder.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Security.Cryptography.X509Certificates; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class OpenSslCertificateFinder : ManagedCertificateFinder { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCrlCache.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCrlCache.cs index 4dd122871b0a7a..d1c4a946c629fb 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCrlCache.cs @@ -1,20 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Formats.Asn1; using System.IO; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates.Asn1; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal static class CrlCache + internal static class OpenSslCrlCache { private static readonly string s_crlDir = PersistedFiles.GetUserFeatureDirectory( @@ -156,7 +153,7 @@ private static void DownloadAndAddCrl( { // X509_STORE_add_crl will increase the refcount on the CRL object, so we should still // dispose our copy. - using (SafeX509CrlHandle? crl = CertificateAssetDownloader.DownloadCrl(url, downloadTimeout)) + using (SafeX509CrlHandle? crl = OpenSslCertificateAssetDownloader.DownloadCrl(url, downloadTimeout)) { // null is a valid return (e.g. no remainingDownloadTime) if (crl != null && !crl.IsInvalid) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/DirectoryBasedStoreProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslDirectoryBasedStoreProvider.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/DirectoryBasedStoreProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslDirectoryBasedStoreProvider.cs index 0928ced4c2784e..085ae91f870d31 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/DirectoryBasedStoreProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslDirectoryBasedStoreProvider.cs @@ -1,21 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Text; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { /// /// Provides an implementation of an X509Store which is backed by files in a directory. /// - internal sealed class DirectoryBasedStoreProvider : IStorePal + internal sealed class OpenSslDirectoryBasedStoreProvider : IStorePal { // {thumbprint}.1.pfx to {thumbprint}.9.pfx private const int MaxSaveAttempts = 9; @@ -32,7 +29,7 @@ internal sealed class DirectoryBasedStoreProvider : IStorePal private readonly bool _readOnly; #if DEBUG - static DirectoryBasedStoreProvider() + static OpenSslDirectoryBasedStoreProvider() { Debug.Assert( 0 == OpenFlags.ReadOnly, @@ -40,7 +37,7 @@ static DirectoryBasedStoreProvider() } #endif - internal DirectoryBasedStoreProvider(string storeName, OpenFlags openFlags) + internal OpenSslDirectoryBasedStoreProvider(string storeName, OpenFlags openFlags) { if (string.IsNullOrEmpty(storeName)) { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ExportProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslExportProvider.cs similarity index 90% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ExportProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslExportProvider.cs index e692706909fb14..e8dcae113b2fe3 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ExportProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslExportProvider.cs @@ -1,22 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; -using System; using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; +using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed class ExportProvider : UnixExportProvider + internal sealed class OpenSslExportProvider : UnixExportProvider { - internal ExportProvider(ICertificatePalCore singleCertPal) + internal OpenSslExportProvider(ICertificatePalCore singleCertPal) : base(singleCertPal) { } - internal ExportProvider(X509Certificate2Collection certs) + internal OpenSslExportProvider(X509Certificate2Collection certs) : base(certs) { } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslPkcs12Reader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcs12Reader.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslPkcs12Reader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcs12Reader.cs index 78acf1c2adac1f..79b7aed738772c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslPkcs12Reader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcs12Reader.cs @@ -1,13 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics.CodeAnalysis; using System.Formats.Asn1; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class OpenSslPkcs12Reader : UnixPkcs12Reader { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/PkcsFormatReader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcsFormatReader.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/PkcsFormatReader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcsFormatReader.cs index b7f10c81a8c66b..4e07816023dae5 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/PkcsFormatReader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcsFormatReader.cs @@ -8,9 +8,9 @@ using System.Security.Cryptography; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal static class PkcsFormatReader + internal static class OpenSslPkcsFormatReader { internal static bool IsPkcs7(ReadOnlySpan rawData) { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/SingleCertLoader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslSingleCertLoader.cs similarity index 79% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/SingleCertLoader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslSingleCertLoader.cs index 0e149ff00c88fc..35ef452c74b6ba 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/SingleCertLoader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslSingleCertLoader.cs @@ -2,16 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Security.Cryptography.X509Certificates; using System.Threading; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed class SingleCertLoader : ILoaderPal + internal sealed class OpenSslSingleCertLoader : ILoaderPal { private ICertificatePal? _cert; - public SingleCertLoader(ICertificatePal cert) + public OpenSslSingleCertLoader(ICertificatePal cert) { _cert = cert; } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509CertificateReader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslX509CertificateReader.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509CertificateReader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslX509CertificateReader.cs index 27f1df388e7f15..5ab92850cbd07b 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509CertificateReader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslX509CertificateReader.cs @@ -1,19 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Text; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class OpenSslX509CertificateReader : ICertificatePal { @@ -53,9 +50,9 @@ public static ICertificatePal FromBlob(ReadOnlySpan rawData, SafePasswordH if (TryReadX509Der(rawData, out cert) || TryReadX509Pem(rawData, out cert) || - PkcsFormatReader.TryReadPkcs7Der(rawData, out cert) || - PkcsFormatReader.TryReadPkcs7Pem(rawData, out cert) || - PkcsFormatReader.TryReadPkcs12(rawData, password, ephemeralSpecified, out cert, out openSslException)) + OpenSslPkcsFormatReader.TryReadPkcs7Der(rawData, out cert) || + OpenSslPkcsFormatReader.TryReadPkcs7Pem(rawData, out cert) || + OpenSslPkcsFormatReader.TryReadPkcs12(rawData, password, ephemeralSpecified, out cert, out openSslException)) { if (cert == null) { @@ -86,7 +83,7 @@ public static ICertificatePal FromFile(string fileName, SafePasswordHandle passw if (pal == null) { - PkcsFormatReader.TryReadPkcs12( + OpenSslPkcsFormatReader.TryReadPkcs12( File.ReadAllBytes(fileName), password, ephemeralSpecified, @@ -127,7 +124,7 @@ public static ICertificatePal FromFile(string fileName, SafePasswordHandle passw // Rewind, try again. RewindBio(bio, bioPosition); - if (PkcsFormatReader.TryReadPkcs7Pem(bio, out certPal)) + if (OpenSslPkcsFormatReader.TryReadPkcs7Pem(bio, out certPal)) { return certPal; } @@ -135,7 +132,7 @@ public static ICertificatePal FromFile(string fileName, SafePasswordHandle passw // Rewind, try again. RewindBio(bio, bioPosition); - if (PkcsFormatReader.TryReadPkcs7Der(bio, out certPal)) + if (OpenSslPkcsFormatReader.TryReadPkcs7Der(bio, out certPal)) { return certPal; } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslX509ChainProcessor.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslX509ChainProcessor.cs index 7ec3e6f8f28ba4..a8d232497f4b39 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslX509ChainProcessor.cs @@ -1,23 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Formats.Asn1; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates.Asn1; using System.Text; using Microsoft.Win32.SafeHandles; +using Internal.Cryptography; using X509VerifyStatusCodeUniversal = Interop.Crypto.X509VerifyStatusCodeUniversal; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class OpenSslX509ChainProcessor : IChainPal { @@ -27,14 +25,14 @@ internal sealed class OpenSslX509ChainProcessor : IChainPal // 10 is plenty big. private const int DefaultChainCapacity = 10; - private static readonly CachedDirectoryStoreProvider s_userRootStore = - new CachedDirectoryStoreProvider(X509Store.RootStoreName); + private static readonly OpenSslCachedDirectoryStoreProvider s_userRootStore = + new OpenSslCachedDirectoryStoreProvider(X509Store.RootStoreName); - private static readonly CachedDirectoryStoreProvider s_userIntermediateStore = - new CachedDirectoryStoreProvider(X509Store.IntermediateCAStoreName); + private static readonly OpenSslCachedDirectoryStoreProvider s_userIntermediateStore = + new OpenSslCachedDirectoryStoreProvider(X509Store.IntermediateCAStoreName); - private static readonly CachedDirectoryStoreProvider s_userPersonalStore = - new CachedDirectoryStoreProvider(X509Store.MyStoreName); + private static readonly OpenSslCachedDirectoryStoreProvider s_userPersonalStore = + new OpenSslCachedDirectoryStoreProvider(X509Store.MyStoreName); // Save the results of GetX509VerifyCertErrorString as we look them up. // On Windows we preload the entire string table, but on Linux we'll delay-load memoize @@ -82,7 +80,7 @@ public void Dispose() public bool? Verify(X509VerificationFlags flags, out Exception? exception) { exception = null; - return ChainVerifier.Verify(ChainElements!, flags); + return UnixChainVerifier.Verify(ChainElements!, flags); } public X509ChainElement[]? ChainElements { get; private set; } @@ -95,12 +93,12 @@ public SafeX509ChainHandle? SafeHandle internal static OpenSslX509ChainProcessor InitiateChain( SafeX509Handle leafHandle, - X509Certificate2Collection customTrustStore, + X509Certificate2Collection? customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan remainingDownloadTime) { - CachedSystemStoreProvider.GetNativeCollections( + OpenSslCachedSystemStoreProvider.GetNativeCollections( out SafeX509StackHandle systemTrust, out SafeX509StackHandle systemIntermediate); @@ -145,7 +143,7 @@ internal static OpenSslX509ChainProcessor InitiateChain( private static SafeX509StoreHandle GetTrustStore( X509ChainTrustMode trustMode, - X509Certificate2Collection customTrustStore, + X509Certificate2Collection? customTrustStore, SafeX509StackHandle untrusted, SafeX509StackHandle systemTrust) { @@ -153,10 +151,17 @@ private static SafeX509StoreHandle GetTrustStore( { using (SafeX509StackHandle customTrust = Interop.Crypto.NewX509Stack()) { - foreach (X509Certificate2 cert in customTrustStore) + if (customTrustStore != null) { - SafeX509StackHandle toAdd = cert.SubjectName.RawData.ContentsEqual(cert.IssuerName.RawData) ? customTrust : untrusted; - AddToStackAndUpRef(((OpenSslX509CertificateReader)cert.Pal!).SafeHandle, toAdd); + foreach (X509Certificate2 cert in customTrustStore) + { + SafeX509StackHandle toAdd = + cert.SubjectName.RawData.ContentsEqual(cert.IssuerName.RawData) ? + customTrust : + untrusted; + + AddToStackAndUpRef(((OpenSslX509CertificateReader)cert.Pal!).SafeHandle, toAdd); + } } return Interop.Crypto.X509ChainNew(customTrust, SafeX509StackHandle.InvalidHandle); @@ -374,7 +379,7 @@ internal void ProcessRevocation( using (SafeX509Handle cert = Interop.Crypto.X509UpRef(Interop.Crypto.GetX509StackField(chainStack, i))) { - CrlCache.AddCrlForCertificate( + OpenSslCrlCache.AddCrlForCertificate( cert, _store, revocationMode, @@ -613,7 +618,7 @@ private WorkingChain BuildWorkingChain() return workingChain; } - internal void Finish(OidCollection applicationPolicy, OidCollection certificatePolicy) + internal void Finish(OidCollection? applicationPolicy, OidCollection? certificatePolicy) { WorkingChain? workingChain = _workingChain; @@ -659,7 +664,7 @@ private Interop.Crypto.X509VerifyStatusCode CheckOcsp( SafeX509Handle certHandle, X509RevocationMode revocationMode) { - string ocspCache = CrlCache.GetCachedOcspResponseDirectory(); + string ocspCache = OpenSslCrlCache.GetCachedOcspResponseDirectory(); Interop.Crypto.X509VerifyStatusCode status = Interop.Crypto.X509ChainGetCachedOcspStatus(_storeCtx, ocspCache, chainDepth); @@ -703,7 +708,7 @@ private Interop.Crypto.X509VerifyStatusCode CheckOcsp( // // So, for now, only try GET. SafeOcspResponseHandle? resp = - CertificateAssetDownloader.DownloadOcspGet(requestUrl, _downloadTimeout); + OpenSslCertificateAssetDownloader.DownloadOcspGet(requestUrl, _downloadTimeout); using (resp) { @@ -864,7 +869,7 @@ private static void ProcessPolicy( X509ChainElement[] elements, ref List? overallStatus, OidCollection? applicationPolicy, - OidCollection certificatePolicy) + OidCollection? certificatePolicy) { List certsToRead = new List(); @@ -1140,7 +1145,7 @@ private static X509ChainStatusFlags MapOpenSsl111Code(Interop.Crypto.X509VerifyS return null; } - return CertificateAssetDownloader.DownloadCertificate(uri, downloadTimeout); + return OpenSslCertificateAssetDownloader.DownloadCertificate(uri, downloadTimeout); } private static string? GetOcspEndpoint(SafeX509Handle cert) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509Encoder.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslX509Encoder.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509Encoder.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslX509Encoder.cs index 5694c2c799206c..a25546c7a44e22 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509Encoder.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslX509Encoder.cs @@ -1,16 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Formats.Asn1; using System.IO; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class OpenSslX509Encoder : ManagedX509ExtensionProcessor, IX509Pal { @@ -78,7 +75,7 @@ public X509ContentType GetCertContentType(ReadOnlySpan rawData) } } - if (PkcsFormatReader.IsPkcs7(rawData)) + if (OpenSslPkcsFormatReader.IsPkcs7(rawData)) { return X509ContentType.Pkcs7; } @@ -133,14 +130,14 @@ public X509ContentType GetCertContentType(string fileName) // X509ContentType.Pkcs7 { - if (PkcsFormatReader.IsPkcs7Der(fileBio)) + if (OpenSslPkcsFormatReader.IsPkcs7Der(fileBio)) { return X509ContentType.Pkcs7; } OpenSslX509CertificateReader.RewindBio(fileBio, bioPosition); - if (PkcsFormatReader.IsPkcs7Pem(fileBio)) + if (OpenSslPkcsFormatReader.IsPkcs7Pem(fileBio)) { return X509ContentType.Pkcs7; } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Pkcs10CertificationRequestInfo.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Pkcs10CertificationRequestInfo.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Pkcs10CertificationRequestInfo.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Pkcs10CertificationRequestInfo.cs index 963ec964381970..ae14cc735a48f3 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Pkcs10CertificationRequestInfo.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Pkcs10CertificationRequestInfo.cs @@ -50,7 +50,7 @@ internal byte[] ToPkcs10Request(X509SignatureGenerator signatureGenerator, HashA signatureAlgorithmAsn = AlgorithmIdentifierAsn.Decode(signatureAlgorithm, AsnEncodingRules.DER); if (signatureAlgorithmAsn.Parameters.HasValue) { - Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value); + Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value.Span); } SubjectPublicKeyInfoAsn spki = default; diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Pkcs9ExtensionRequest.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Pkcs9ExtensionRequest.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/Pkcs9ExtensionRequest.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Pkcs9ExtensionRequest.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/PublicKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/PublicKey.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/PublicKey.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/PublicKey.cs index 129932a334505b..33f24dd1f50a59 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/PublicKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/PublicKey.cs @@ -1,16 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; using System.Formats.Asn1; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Cryptography.Asn1; -using Internal.Cryptography; -using Internal.Cryptography.Pal; - namespace System.Security.Cryptography.X509Certificates { public sealed class PublicKey @@ -152,6 +148,7 @@ public static PublicKey CreateFromSubjectPublicKeyInfo(ReadOnlySpan source /// /// The key contents are corrupt or could not be read successfully. /// + [UnsupportedOSPlatform("browser")] public RSA? GetRSAPublicKey() { if (_oid.Value != Oids.Rsa) @@ -180,6 +177,7 @@ public static PublicKey CreateFromSubjectPublicKeyInfo(ReadOnlySpan source /// /// The key contents are corrupt or could not be read successfully. /// + [UnsupportedOSPlatform("browser")] [UnsupportedOSPlatform("ios")] [UnsupportedOSPlatform("tvos")] public DSA? GetDSAPublicKey() @@ -210,6 +208,7 @@ public static PublicKey CreateFromSubjectPublicKeyInfo(ReadOnlySpan source /// /// The key contents are corrupt or could not be read successfully. /// + [UnsupportedOSPlatform("browser")] public ECDsa? GetECDsaPublicKey() { if (_oid.Value != Oids.EcPublicKey) @@ -239,6 +238,7 @@ public static PublicKey CreateFromSubjectPublicKeyInfo(ReadOnlySpan source /// /// The key contents are corrupt or could not be read successfully. /// + [UnsupportedOSPlatform("browser")] public ECDiffieHellman? GetECDiffieHellmanPublicKey() { if (_oid.Value != Oids.EcPublicKey) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/RSACertificateExtensions.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSACertificateExtensions.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/RSACertificateExtensions.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSACertificateExtensions.cs index e38450eccdc8c6..f88157eec37d4b 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/RSACertificateExtensions.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSACertificateExtensions.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography; -using Internal.Cryptography.Pal; namespace System.Security.Cryptography.X509Certificates { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs index 8320dc0ade08ad..c1daad2b756e25 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs @@ -37,17 +37,17 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg if (hashAlgorithm == HashAlgorithmName.SHA256) { - cbSalt = 256 / 8; + cbSalt = SHA256.HashSizeInBytes; digestOid = Oids.Sha256; } else if (hashAlgorithm == HashAlgorithmName.SHA384) { - cbSalt = 384 / 8; + cbSalt = SHA384.HashSizeInBytes; digestOid = Oids.Sha384; } else if (hashAlgorithm == HashAlgorithmName.SHA512) { - cbSalt = 512 / 8; + cbSalt = SHA512.HashSizeInBytes; digestOid = Oids.Sha512; } else diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/SafeHandles.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/SafeLocalAllocHandle.cs similarity index 93% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/SafeHandles.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/SafeLocalAllocHandle.cs index c9cf3d62fe0559..1fe163b1d5617c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/SafeHandles.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/SafeLocalAllocHandle.cs @@ -6,7 +6,7 @@ #pragma warning disable CA1419 // TODO https://github.com/dotnet/roslyn-analyzers/issues/5232: not intended for use with P/Invoke -namespace Internal.Cryptography.Pal.Native +namespace System.Security.Cryptography.X509Certificates { /// /// SafeHandle for LocalAlloc'd memory. diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/StoreLocation.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StoreLocation.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/StoreLocation.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StoreLocation.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/StoreName.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StoreName.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/StoreName.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StoreName.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.AndroidKeyStore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.AndroidKeyStore.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs index 898d79c292da35..4a1abe1bd9a2b1 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.AndroidKeyStore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs @@ -1,15 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.ExportPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.ExportPal.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.ExportPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.ExportPal.cs index b98ed829663160..fd08bb0f525d33 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.ExportPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.ExportPal.cs @@ -1,12 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.LoaderPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.LoaderPal.cs similarity index 91% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.LoaderPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.LoaderPal.cs index cadb90643ce089..0bf66a2c3e6d4c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.LoaderPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.LoaderPal.cs @@ -1,14 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Threading; +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.TrustedStore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.TrustedStore.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.TrustedStore.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.TrustedStore.cs index 6998610bd1c395..d6089421860a9f 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.TrustedStore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.TrustedStore.cs @@ -1,15 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.cs similarity index 86% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.cs index 6187979d905f87..7c31e1f3734354 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/StorePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.cs @@ -1,24 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { - public static IStorePal FromHandle(IntPtr storeHandle) + internal static partial IStorePal FromHandle(IntPtr storeHandle) { throw new NotImplementedException($"{nameof(StorePal)}.{nameof(FromHandle)}"); } - public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); @@ -37,23 +34,23 @@ public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle } } - public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { byte[] fileBytes = File.ReadAllBytes(fileName); return FromBlob(fileBytes, password, keyStorageFlags); } - public static IExportPal FromCertificate(ICertificatePalCore cert) + internal static partial IExportPal FromCertificate(ICertificatePalCore cert) { return new AndroidExportProvider(cert); } - public static IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) + internal static partial IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) { return new AndroidExportProvider(certificates); } - public static IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) + internal static partial IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) { bool isReadWrite = (openFlags & OpenFlags.ReadWrite) == OpenFlags.ReadWrite; if (isReadWrite && storeLocation == StoreLocation.LocalMachine) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.NotSupported.cs new file mode 100644 index 00000000000000..2b7706b4a7a63a --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.NotSupported.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class StorePal + { + internal static partial IStorePal FromHandle(IntPtr storeHandle) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial ILoaderPal FromBlob( + ReadOnlySpan rawData, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial ILoaderPal FromFile( + string fileName, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial IExportPal FromCertificate(ICertificatePalCore cert) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial IExportPal LinkFromCertificateCollection( + X509Certificate2Collection certificates) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + + internal static partial IStorePal FromSystemStore( + string storeName, + StoreLocation storeLocation, + OpenFlags openFlags) + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/StorePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.OpenSsl.cs similarity index 75% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/StorePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.OpenSsl.cs index bef72007c383a1..e1c4a49284961c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/StorePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.OpenSsl.cs @@ -1,24 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { - public static IStorePal FromHandle(IntPtr storeHandle) + internal static partial IStorePal FromHandle(IntPtr storeHandle) { throw new PlatformNotSupportedException(); } - public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); @@ -38,9 +35,9 @@ public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle List? certPals; Exception? openSslException; - if (PkcsFormatReader.TryReadPkcs7Der(rawData, out certPals) || - PkcsFormatReader.TryReadPkcs7Pem(rawData, out certPals) || - PkcsFormatReader.TryReadPkcs12(rawData, password, ephemeralSpecified, out certPals, out openSslException)) + if (OpenSslPkcsFormatReader.TryReadPkcs7Der(rawData, out certPals) || + OpenSslPkcsFormatReader.TryReadPkcs7Pem(rawData, out certPals) || + OpenSslPkcsFormatReader.TryReadPkcs12(rawData, password, ephemeralSpecified, out certPals, out openSslException)) { Debug.Assert(certPals != null); @@ -51,7 +48,7 @@ public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle throw openSslException; } - public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { bool ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet); @@ -92,7 +89,7 @@ private static ILoaderPal FromBio( List? certPals; - if (PkcsFormatReader.TryReadPkcs7Pem(bio, out certPals)) + if (OpenSslPkcsFormatReader.TryReadPkcs7Pem(bio, out certPals)) { return ListToLoaderPal(certPals); } @@ -100,7 +97,7 @@ private static ILoaderPal FromBio( // Rewind, try again. OpenSslX509CertificateReader.RewindBio(bio, bioPosition); - if (PkcsFormatReader.TryReadPkcs7Der(bio, out certPals)) + if (OpenSslPkcsFormatReader.TryReadPkcs7Der(bio, out certPals)) { return ListToLoaderPal(certPals); } @@ -111,7 +108,7 @@ private static ILoaderPal FromBio( // Capture the exception so in case of failure, the call to BioSeek does not override it. Exception? openSslException; byte[] data = File.ReadAllBytes(fileName); - if (PkcsFormatReader.TryReadPkcs12(data, password, ephemeralSpecified, out certPals, out openSslException)) + if (OpenSslPkcsFormatReader.TryReadPkcs12(data, password, ephemeralSpecified, out certPals, out openSslException)) { return ListToLoaderPal(certPals); } @@ -130,26 +127,26 @@ private static ILoaderPal FromBio( throw openSslException; } - public static IExportPal FromCertificate(ICertificatePalCore cert) + internal static partial IExportPal FromCertificate(ICertificatePalCore cert) { - return new ExportProvider(cert); + return new OpenSslExportProvider(cert); } - public static IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) + internal static partial IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) { - return new ExportProvider(certificates); + return new OpenSslExportProvider(certificates); } - public static IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) + internal static partial IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) { if (storeLocation == StoreLocation.CurrentUser) { if (X509Store.DisallowedStoreName.Equals(storeName, StringComparison.OrdinalIgnoreCase)) { - return DirectoryBasedStoreProvider.OpenDisallowedStore(openFlags); + return OpenSslDirectoryBasedStoreProvider.OpenDisallowedStore(openFlags); } - return new DirectoryBasedStoreProvider(storeName, openFlags); + return new OpenSslDirectoryBasedStoreProvider(storeName, openFlags); } Debug.Assert(storeLocation == StoreLocation.LocalMachine); @@ -167,12 +164,12 @@ public static IStorePal FromSystemStore(string storeName, StoreLocation storeLoc if (X509Store.RootStoreName.Equals(storeName, StringComparison.OrdinalIgnoreCase)) { - return CachedSystemStoreProvider.MachineRoot; + return OpenSslCachedSystemStoreProvider.MachineRoot; } if (X509Store.IntermediateCAStoreName.Equals(storeName, StringComparison.OrdinalIgnoreCase)) { - return CachedSystemStoreProvider.MachineIntermediate; + return OpenSslCachedSystemStoreProvider.MachineIntermediate; } throw new CryptographicException( @@ -182,7 +179,7 @@ public static IStorePal FromSystemStore(string storeName, StoreLocation storeLoc private static ILoaderPal SingleCertToLoaderPal(ICertificatePal singleCert) { - return new SingleCertLoader(singleCert); + return new OpenSslSingleCertLoader(singleCert); } private static ILoaderPal ListToLoaderPal(List certPals) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Export.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Windows.Export.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Export.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Windows.Export.cs index 2a44fb6aba75e5..b6bc38933fb857 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Export.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Windows.Export.cs @@ -1,14 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; -using System; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal : IDisposable, IStorePal, IExportPal, ILoaderPal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Import.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Windows.Import.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Import.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Windows.Import.cs index ed4c5386e74bf1..264e1bf11fb6de 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Import.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Windows.Import.cs @@ -1,24 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography.Pal.Native; -using Microsoft.Win32.SafeHandles; -using System; +using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -using System.Security.Cryptography.X509Certificates; -using System.Diagnostics; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal : IDisposable, IStorePal, IExportPal, ILoaderPal { - public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return FromBlobOrFile(rawData, null, password, keyStorageFlags); } - public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { return FromBlobOrFile(null, fileName, password, keyStorageFlags); } @@ -99,7 +97,7 @@ private static StorePal FromBlobOrFile(ReadOnlySpan rawData, string? fileN } } - public static IExportPal FromCertificate(ICertificatePalCore cert) + internal static partial IExportPal FromCertificate(ICertificatePalCore cert) { CertificatePal certificatePal = (CertificatePal)cert; @@ -120,7 +118,7 @@ public static IExportPal FromCertificate(ICertificatePalCore cert) /// Note: this factory method creates the store using links to the original certificates rather than copies. This means that any changes to certificate properties /// in the store changes the original. /// - public static IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) + internal static partial IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) { // we always want to use CERT_STORE_ENUM_ARCHIVED_FLAG since we want to preserve the collection in this operation. // By default, Archived certificates will not be included. @@ -149,7 +147,7 @@ public static IExportPal LinkFromCertificateCollection(X509Certificate2Collectio return new StorePal(certStore); } - public static IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) + internal static partial IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) { Interop.Crypt32.CertStoreFlags certStoreFlags = MapX509StoreFlags(storeLocation, openFlags); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Windows.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Windows.cs index 47bbfe4c7988dd..f2e6494481f620 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Windows.cs @@ -1,20 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; -using System; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography.X509Certificates; -using System.Security.Cryptography; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal : IDisposable, IStorePal, IExportPal, ILoaderPal { private SafeCertStoreHandle _certStore; - public static IStorePal FromHandle(IntPtr storeHandle) + internal static partial IStorePal FromHandle(IntPtr storeHandle) { if (storeHandle == IntPtr.Zero) throw new ArgumentNullException(nameof(storeHandle)); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.cs new file mode 100644 index 00000000000000..54a29a92fd65a6 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.X509Certificates +{ + internal partial class StorePal + { + internal static partial IStorePal FromHandle(IntPtr storeHandle); + + internal static partial ILoaderPal FromBlob( + ReadOnlySpan rawData, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags); + + internal static partial ILoaderPal FromFile( + string fileName, + SafePasswordHandle password, + X509KeyStorageFlags keyStorageFlags); + + internal static partial IExportPal FromCertificate(ICertificatePalCore cert); + + internal static partial IExportPal LinkFromCertificateCollection( + X509Certificate2Collection certificates); + + internal static partial IStorePal FromSystemStore( + string storeName, + StoreLocation storeLocation, + OpenFlags openFlags); + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/StorePal.AppleKeychainStore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.AppleKeychainStore.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/StorePal.AppleKeychainStore.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.AppleKeychainStore.cs index 88be19a1e03d57..b320c022ae2487 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/StorePal.AppleKeychainStore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.AppleKeychainStore.cs @@ -1,16 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; -using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/StorePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.cs similarity index 86% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/StorePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.cs index 47d7485c0f9847..3e8c5acfd25ae7 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/StorePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.cs @@ -1,25 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Security.Cryptography; -using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { - public static IStorePal FromHandle(IntPtr storeHandle) + internal static partial IStorePal FromHandle(IntPtr storeHandle) { throw new PlatformNotSupportedException($"{nameof(StorePal)}.{nameof(FromHandle)}"); } - public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { List? certificateList = null; @@ -85,7 +81,7 @@ public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle if (handle != IntPtr.Zero) { - ICertificatePal? certPal = CertificatePal.FromHandle(handle, throwOnFail: false); + ICertificatePal? certPal = AppleCertificatePal.FromHandle(handle, throwOnFail: false); if (certPal != null) { @@ -98,7 +94,7 @@ public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle return new CertCollectionLoader(certificateList); } - public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); @@ -106,17 +102,17 @@ public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, return FromBlob(fileBytes, password, keyStorageFlags); } - public static IExportPal FromCertificate(ICertificatePalCore cert) + internal static partial IExportPal FromCertificate(ICertificatePalCore cert) { return new AppleCertificateExporter(cert); } - public static IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) + internal static partial IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) { return new AppleCertificateExporter(certificates); } - public static IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) + internal static partial IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) { StringComparer ordinalIgnoreCase = StringComparer.OrdinalIgnoreCase; diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.AppleKeychainStore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.AppleKeychainStore.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.AppleKeychainStore.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.AppleKeychainStore.cs index c04a55f25a97fc..7606d326495ba7 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.AppleKeychainStore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.AppleKeychainStore.cs @@ -1,16 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.AppleTrustStore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.AppleTrustStore.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.AppleTrustStore.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.AppleTrustStore.cs index e5cb0f882d3867..6cbfb9cd0f62be 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.AppleTrustStore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.AppleTrustStore.cs @@ -1,15 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.ExportPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.ExportPal.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.ExportPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.ExportPal.cs index c29221ad79ec36..eac97c8cead254 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.ExportPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.ExportPal.cs @@ -1,13 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -using Microsoft.Win32.SafeHandles; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.LoaderPal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.LoaderPal.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.LoaderPal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.LoaderPal.cs index a05387db060fa2..c6f33bbf1ce3ed 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.LoaderPal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.LoaderPal.cs @@ -1,14 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using System.Threading; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { @@ -45,7 +42,7 @@ public void MoveTo(X509Certificate2Collection collection) if (handle != IntPtr.Zero) { - ICertificatePal? certPal = CertificatePal.FromHandle(handle, throwOnFail: false); + ICertificatePal? certPal = AppleCertificatePal.FromHandle(handle, throwOnFail: false); if (certPal != null) { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.cs similarity index 90% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.cs index e7cbefeb5b4d52..cfd418b27a545f 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/StorePal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.macOS.cs @@ -1,20 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class StorePal { - public static IStorePal FromHandle(IntPtr storeHandle) + internal static partial IStorePal FromHandle(IntPtr storeHandle) { if (storeHandle == IntPtr.Zero) throw new ArgumentNullException(nameof(storeHandle)); @@ -25,7 +22,7 @@ public static IStorePal FromHandle(IntPtr storeHandle) return new AppleKeychainStore(keychainHandle, OpenFlags.MaxAllowed); } - public static ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromBlob(ReadOnlySpan rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); @@ -82,7 +79,7 @@ private static ILoaderPal ImportPkcs12( } } - public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) + internal static partial ILoaderPal FromFile(string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) { Debug.Assert(password != null); @@ -90,17 +87,17 @@ public static ILoaderPal FromFile(string fileName, SafePasswordHandle password, return FromBlob(fileBytes, password, keyStorageFlags); } - public static IExportPal FromCertificate(ICertificatePalCore cert) + internal static partial IExportPal FromCertificate(ICertificatePalCore cert) { return new AppleCertificateExporter(cert); } - public static IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) + internal static partial IExportPal LinkFromCertificateCollection(X509Certificate2Collection certificates) { return new AppleCertificateExporter(certificates); } - public static IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) + internal static partial IStorePal FromSystemStore(string storeName, StoreLocation storeLocation, OpenFlags openFlags) { StringComparer ordinalIgnoreCase = StringComparer.OrdinalIgnoreCase; diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/SubjectAlternativeNameBuilder.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/SubjectAlternativeNameBuilder.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/SubjectAlternativeNameBuilder.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/SubjectAlternativeNameBuilder.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainVerifier.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixChainVerifier.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainVerifier.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixChainVerifier.cs index d9b6839f4b6fb7..73e195d7d1b840 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/ChainVerifier.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixChainVerifier.cs @@ -1,15 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; +using Internal.Cryptography; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal static class ChainVerifier + internal static class UnixChainVerifier { public static bool Verify(X509ChainElement[] chainElements, X509VerificationFlags flags) { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/UnixExportProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixExportProvider.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/UnixExportProvider.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixExportProvider.cs index a6e50de9d44077..f569435e605c61 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/UnixExportProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixExportProvider.cs @@ -1,19 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Win32.SafeHandles; -using System; using System.Buffers; using System.Diagnostics; using System.Formats.Asn1; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; using System.Security.Cryptography.Asn1.Pkcs12; using System.Security.Cryptography.Pkcs; -using System.Security.Cryptography.X509Certificates; +using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal abstract class UnixExportProvider : IExportPal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/UnixPkcs12Reader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixPkcs12Reader.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/UnixPkcs12Reader.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixPkcs12Reader.cs index 8cd7abe0660a88..f7454d5b7aae1c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/UnixPkcs12Reader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixPkcs12Reader.cs @@ -1,20 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.Formats.Asn1; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Security.Cryptography.Asn1; using System.Security.Cryptography.Asn1.Pkcs12; using System.Security.Cryptography.Asn1.Pkcs7; using System.Threading; +using Internal.Cryptography; using Microsoft.Win32.SafeHandles; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal abstract class UnixPkcs12Reader : IDisposable { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/UnsupportedDisallowedStore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnsupportedDisallowedStore.cs similarity index 92% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/UnsupportedDisallowedStore.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnsupportedDisallowedStore.cs index fbdcd08bceb752..e4b068f9ace421 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/UnsupportedDisallowedStore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnsupportedDisallowedStore.cs @@ -1,16 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Text; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed class UnsupportedDisallowedStore : IStorePal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Helpers.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/WindowsHelpers.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Helpers.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/WindowsHelpers.cs index 07dc27d9a39b30..fe3fa41389c1cc 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Helpers.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/WindowsHelpers.cs @@ -5,11 +5,12 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; using System.Text; -namespace Internal.Cryptography.Pal.Native +namespace Internal.Cryptography { - internal static class Helpers + internal static partial class Helpers { /// /// Convert each Oid's value to an ASCII string, then create an unmanaged array of "numOids" LPSTR pointers, one for each Oid. diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.crypt32.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/WindowsInterop.crypt32.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.crypt32.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/WindowsInterop.crypt32.cs index 8df13c01e359c6..fea9b7698e97d4 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.crypt32.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/WindowsInterop.crypt32.cs @@ -11,9 +11,9 @@ using SafeNCryptKeyHandle = Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle; using Internal.Cryptography; -using Internal.Cryptography.Pal.Native; using Microsoft.Win32.SafeHandles; using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography.X509Certificates; internal static partial class Interop { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Primitives.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/WindowsStructs.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Primitives.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/WindowsStructs.cs index bec34b98cd60c9..5746b4bdc3a164 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Primitives.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/WindowsStructs.cs @@ -1,10 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Runtime.InteropServices; -namespace Internal.Cryptography.Pal.Native +namespace System.Security.Cryptography.X509Certificates { internal enum CertStoreProvider : int { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500DictionaryStringHelper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500DictionaryStringHelper.cs new file mode 100644 index 00000000000000..4edef81da00f2a --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500DictionaryStringHelper.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Formats.Asn1; + +namespace System.Security.Cryptography.X509Certificates +{ + internal static class X500DictionaryStringHelper + { + internal static string ReadAnyAsnString(this AsnReader tavReader) + { + Asn1Tag tag = tavReader.PeekTag(); + + if (tag.TagClass != TagClass.Universal) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + switch ((UniversalTagNumber)tag.TagValue) + { + case UniversalTagNumber.BMPString: + case UniversalTagNumber.IA5String: + case UniversalTagNumber.NumericString: + case UniversalTagNumber.PrintableString: + case UniversalTagNumber.UTF8String: + case UniversalTagNumber.T61String: + // .NET's string comparisons start by checking the length, so a trailing + // NULL character which was literally embedded in the DER would cause a + // failure in .NET whereas it wouldn't have with strcmp. + return tavReader.ReadCharacterString((UniversalTagNumber)tag.TagValue).TrimEnd('\0'); + + default: + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X500DistinguishedName.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500DistinguishedName.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X500DistinguishedName.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500DistinguishedName.cs index cba36485d7a6d3..0e8dc7efc9cab2 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X500DistinguishedName.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500DistinguishedName.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography.Pal; - namespace System.Security.Cryptography.X509Certificates { public sealed class X500DistinguishedName : AsnEncodedData diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X500DistinguishedNameFlags.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500DistinguishedNameFlags.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X500DistinguishedNameFlags.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500DistinguishedNameFlags.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.ManagedDecode.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.ManagedDecode.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.ManagedDecode.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.ManagedDecode.cs index 7a4086135052f0..d91d1054ced1b9 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.ManagedDecode.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.ManagedDecode.cs @@ -1,13 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Formats.Asn1; -using System.Security.Cryptography; using System.Text; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal static partial class X500NameEncoder { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.cs index d68964a48f5417..ff7393c794b6d4 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X500NameEncoder.cs @@ -1,15 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Text; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal static partial class X500NameEncoder { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X501Attribute.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X501Attribute.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X501Attribute.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X501Attribute.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs similarity index 91% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs index 013c6cac85639c..fd7d5373af68d1 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs @@ -1,16 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.IO; -using System.Text; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.InteropServices; - -using Internal.Cryptography; -using Internal.Cryptography.Pal; - namespace System.Security.Cryptography.X509Certificates { public sealed class X509BasicConstraintsExtension : X509Extension @@ -73,7 +63,7 @@ public override void CopyFrom(AsnEncodedData asnEncodedData) private static byte[] EncodeExtension(bool certificateAuthority, bool hasPathLengthConstraint, int pathLengthConstraint) { if (hasPathLengthConstraint && pathLengthConstraint < 0) - throw new ArgumentOutOfRangeException(nameof(pathLengthConstraint), SR.Arg_OutOfRange_NeedNonNegNum); + throw new ArgumentOutOfRangeException(nameof(pathLengthConstraint), SR.ArgumentOutOfRange_NeedNonNegNum); return X509Pal.Instance.EncodeX509BasicConstraints2Extension(certificateAuthority, hasPathLengthConstraint, pathLengthConstraint); } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate.cs index 1913afa2af2306..a17dbf0f21dd8a 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate.cs @@ -2,13 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography; -using Internal.Cryptography.Pal; using Microsoft.Win32.SafeHandles; -using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.Serialization; +using System.Runtime.Versioning; using System.Text; namespace System.Security.Cryptography.X509Certificates @@ -46,11 +45,13 @@ public virtual void Reset() } [Obsolete(Obsoletions.X509CertificateImmutableMessage, DiagnosticId = Obsoletions.X509CertificateImmutableDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] + [UnsupportedOSPlatform("browser")] public X509Certificate() { } // Null turns into the empty span here, which is correct for compat. + [UnsupportedOSPlatform("browser")] public X509Certificate(byte[] data) : this(new ReadOnlySpan(data)) { @@ -68,17 +69,20 @@ private protected X509Certificate(ReadOnlySpan data) } } + [UnsupportedOSPlatform("browser")] public X509Certificate(byte[] rawData, string? password) : this(rawData, password, X509KeyStorageFlags.DefaultKeySet) { } - [System.CLSCompliantAttribute(false)] + [UnsupportedOSPlatform("browser")] + [CLSCompliantAttribute(false)] public X509Certificate(byte[] rawData, SecureString? password) : this(rawData, password, X509KeyStorageFlags.DefaultKeySet) { } + [UnsupportedOSPlatform("browser")] public X509Certificate(byte[] rawData, string? password, X509KeyStorageFlags keyStorageFlags) { if (rawData == null || rawData.Length == 0) @@ -92,7 +96,8 @@ public X509Certificate(byte[] rawData, string? password, X509KeyStorageFlags key } } - [System.CLSCompliantAttribute(false)] + [UnsupportedOSPlatform("browser")] + [CLSCompliantAttribute(false)] public X509Certificate(byte[] rawData, SecureString? password, X509KeyStorageFlags keyStorageFlags) { if (rawData == null || rawData.Length == 0) @@ -119,6 +124,7 @@ private protected X509Certificate(ReadOnlySpan rawData, ReadOnlySpan } } + [UnsupportedOSPlatform("browser")] public X509Certificate(IntPtr handle) { Pal = CertificatePal.FromHandle(handle); @@ -130,22 +136,26 @@ internal X509Certificate(ICertificatePalCore pal) Pal = pal; } + [UnsupportedOSPlatform("browser")] public X509Certificate(string fileName) : this(fileName, (string?)null, X509KeyStorageFlags.DefaultKeySet) { } + [UnsupportedOSPlatform("browser")] public X509Certificate(string fileName, string? password) : this(fileName, password, X509KeyStorageFlags.DefaultKeySet) { } - [System.CLSCompliantAttribute(false)] + [UnsupportedOSPlatform("browser")] + [CLSCompliantAttribute(false)] public X509Certificate(string fileName, SecureString? password) : this(fileName, password, X509KeyStorageFlags.DefaultKeySet) { } + [UnsupportedOSPlatform("browser")] public X509Certificate(string fileName, string? password, X509KeyStorageFlags keyStorageFlags) { if (fileName == null) @@ -172,7 +182,8 @@ private protected X509Certificate(string fileName, ReadOnlySpan password, } } - [System.CLSCompliantAttribute(false)] + [UnsupportedOSPlatform("browser")] + [CLSCompliantAttribute(false)] #pragma warning disable SYSLIB0026 public X509Certificate(string fileName, SecureString? password, X509KeyStorageFlags keyStorageFlags) : this() #pragma warning restore SYSLIB0026 @@ -188,6 +199,7 @@ public X509Certificate(string fileName, SecureString? password, X509KeyStorageFl } } + [UnsupportedOSPlatform("browser")] public X509Certificate(X509Certificate cert) { if (cert == null) @@ -206,11 +218,13 @@ public X509Certificate(SerializationInfo info, StreamingContext context) : this( throw new PlatformNotSupportedException(); } + [UnsupportedOSPlatform("browser")] public static X509Certificate CreateFromCertFile(string filename) { return new X509Certificate(filename); } + [UnsupportedOSPlatform("browser")] public static X509Certificate CreateFromSignedFile(string filename) { return new X509Certificate(filename); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs index f073ed7afb451b..0de268a2d60c1c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs @@ -1,17 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography; -using Internal.Cryptography.Pal; -using System; using System.Diagnostics; using System.Formats.Asn1; using System.IO; using System.Runtime.Serialization; using System.Runtime.Versioning; -using System.Security; using System.Security.Cryptography.X509Certificates.Asn1; using System.Text; +using Internal.Cryptography; namespace System.Security.Cryptography.X509Certificates { @@ -44,33 +41,39 @@ public override void Reset() } [Obsolete(Obsoletions.X509CertificateImmutableMessage, DiagnosticId = Obsoletions.X509CertificateImmutableDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] + [UnsupportedOSPlatform("browser")] public X509Certificate2() : base() { } + [UnsupportedOSPlatform("browser")] public X509Certificate2(byte[] rawData) : base(rawData) { } + [UnsupportedOSPlatform("browser")] public X509Certificate2(byte[] rawData, string? password) : base(rawData, password) { } - [System.CLSCompliantAttribute(false)] + [UnsupportedOSPlatform("browser")] + [CLSCompliantAttribute(false)] public X509Certificate2(byte[] rawData, SecureString? password) : base(rawData, password) { } + [UnsupportedOSPlatform("browser")] public X509Certificate2(byte[] rawData, string? password, X509KeyStorageFlags keyStorageFlags) : base(rawData, password, keyStorageFlags) { } - [System.CLSCompliantAttribute(false)] + [UnsupportedOSPlatform("browser")] + [CLSCompliantAttribute(false)] public X509Certificate2(byte[] rawData, SecureString? password, X509KeyStorageFlags keyStorageFlags) : base(rawData, password, keyStorageFlags) { @@ -83,6 +86,7 @@ public X509Certificate2(byte[] rawData, SecureString? password, X509KeyStorageFl /// The certificate data to process. /// /// An error with the certificate occurs. + [UnsupportedOSPlatform("browser")] public X509Certificate2(ReadOnlySpan rawData) : base(rawData) { @@ -102,11 +106,13 @@ public X509Certificate2(ReadOnlySpan rawData) /// A bitwise combination of the enumeration values that control where and how to import the certificate. /// /// An error with the certificate occurs. + [UnsupportedOSPlatform("browser")] public X509Certificate2(ReadOnlySpan rawData, ReadOnlySpan password, X509KeyStorageFlags keyStorageFlags = 0) : base(rawData, password, keyStorageFlags) { } + [UnsupportedOSPlatform("browser")] public X509Certificate2(IntPtr handle) : base(handle) { @@ -117,39 +123,45 @@ internal X509Certificate2(ICertificatePal pal) { } + [UnsupportedOSPlatform("browser")] public X509Certificate2(string fileName) : base(fileName) { } + [UnsupportedOSPlatform("browser")] public X509Certificate2(string fileName, string? password) : base(fileName, password) { } - [System.CLSCompliantAttribute(false)] + [UnsupportedOSPlatform("browser")] + [CLSCompliantAttribute(false)] public X509Certificate2(string fileName, SecureString? password) : base(fileName, password) { } - + [UnsupportedOSPlatform("browser")] public X509Certificate2(string fileName, string? password, X509KeyStorageFlags keyStorageFlags) : base(fileName, password, keyStorageFlags) { } - [System.CLSCompliantAttribute(false)] + [UnsupportedOSPlatform("browser")] + [CLSCompliantAttribute(false)] public X509Certificate2(string fileName, SecureString? password, X509KeyStorageFlags keyStorageFlags) : base(fileName, password, keyStorageFlags) { } + [UnsupportedOSPlatform("browser")] public X509Certificate2(string fileName, ReadOnlySpan password, X509KeyStorageFlags keyStorageFlags = 0) : base(fileName, password, keyStorageFlags) { } + [UnsupportedOSPlatform("browser")] public X509Certificate2(X509Certificate certificate) : base(certificate) { @@ -389,6 +401,7 @@ public int Version } } + [UnsupportedOSPlatform("browser")] public static X509ContentType GetCertContentType(byte[] rawData) { if (rawData == null || rawData.Length == 0) @@ -406,6 +419,7 @@ public static X509ContentType GetCertContentType(byte[] rawData) /// /// One of the enumeration values that indicate the content type of the provided data. /// + [UnsupportedOSPlatform("browser")] public static X509ContentType GetCertContentType(ReadOnlySpan rawData) { if (rawData.Length == 0) @@ -414,6 +428,7 @@ public static X509ContentType GetCertContentType(ReadOnlySpan rawData) return X509Pal.Instance.GetCertContentType(rawData); } + [UnsupportedOSPlatform("browser")] public static X509ContentType GetCertContentType(string fileName) { if (fileName == null) @@ -833,6 +848,7 @@ public X509Certificate2 CopyWithPrivateKey(ECDiffieHellman privateKey) /// For password protected PEM-encoded keys, use to specify a password. /// /// + [UnsupportedOSPlatform("browser")] public static X509Certificate2 CreateFromPemFile(string certPemFilePath, string? keyPemFilePath = default) { if (certPemFilePath is null) @@ -899,6 +915,7 @@ public static X509Certificate2 CreateFromPemFile(string certPemFilePath, string? /// For PEM-encoded keys without a password, use . /// /// + [UnsupportedOSPlatform("browser")] public static X509Certificate2 CreateFromEncryptedPemFile(string certPemFilePath, ReadOnlySpan password, string? keyPemFilePath = default) { if (certPemFilePath is null) @@ -949,6 +966,7 @@ public static X509Certificate2 CreateFromEncryptedPemFile(string certPemFilePath /// For password protected PEM-encoded keys, use to specify a password. /// /// + [UnsupportedOSPlatform("browser")] public static X509Certificate2 CreateFromPem(ReadOnlySpan certPem, ReadOnlySpan keyPem) { using (X509Certificate2 certificate = CreateFromPem(certPem)) @@ -1019,6 +1037,7 @@ Oids.EcPublicKey when IsECDiffieHellman(certificate) => /// For PEM-encoded keys without a password, use . /// /// + [UnsupportedOSPlatform("browser")] public static X509Certificate2 CreateFromEncryptedPem(ReadOnlySpan certPem, ReadOnlySpan keyPem, ReadOnlySpan password) { using (X509Certificate2 certificate = CreateFromPem(certPem)) @@ -1083,6 +1102,7 @@ private static bool IsECDiffieHellman(X509Certificate2 certificate) /// For PEM-encoded certificates in a file, use . /// /// + [UnsupportedOSPlatform("browser")] public static X509Certificate2 CreateFromPem(ReadOnlySpan certPem) { foreach ((ReadOnlySpan contents, PemFields fields) in new PemEnumerator(certPem)) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate2Collection.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2Collection.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate2Collection.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2Collection.cs index 5520ea204eea98..314715e3764603 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate2Collection.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2Collection.cs @@ -1,14 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography; -using Internal.Cryptography.Pal; -using Microsoft.Win32.SafeHandles; using System.Diagnostics; using System.Formats.Asn1; using System.Runtime.Versioning; using System.Security.Cryptography.X509Certificates.Asn1; using System.Collections.Generic; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography.X509Certificates { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate2Enumerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2Enumerator.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate2Enumerator.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2Enumerator.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509CertificateCollection.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateCollection.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509CertificateCollection.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateCollection.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509CertificateEnumerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateEnumerator.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509CertificateEnumerator.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateEnumerator.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Chain.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Chain.cs index 7260b772f46ced..03cd945bd03cfa 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Chain.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Chain.cs @@ -1,11 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using SafeX509ChainHandle = Microsoft.Win32.SafeHandles.SafeX509ChainHandle; -using Internal.Cryptography.Pal; using System.Diagnostics; using System.Runtime.Versioning; +using SafeX509ChainHandle = Microsoft.Win32.SafeHandles.SafeX509ChainHandle; + namespace System.Security.Cryptography.X509Certificates { public class X509Chain : IDisposable @@ -102,6 +102,7 @@ public SafeX509ChainHandle? SafeHandle } } + [UnsupportedOSPlatform("browser")] public bool Build(X509Certificate2 certificate) { return Build(certificate, true); @@ -139,7 +140,7 @@ internal bool Build(X509Certificate2 certificate, bool throwOnException) chainPolicy._certificatePolicy!, chainPolicy.RevocationMode, chainPolicy.RevocationFlag, - chainPolicy.CustomTrustStore, + chainPolicy._customTrustStore, chainPolicy.TrustMode, chainPolicy.VerificationTime, chainPolicy.UrlRetrievalTimeout, diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainElement.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainElement.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainElement.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainElement.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainElementCollection.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainElementCollection.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainElementCollection.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainElementCollection.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainElementEnumerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainElementEnumerator.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainElementEnumerator.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainElementEnumerator.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainPolicy.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainPolicy.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainPolicy.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainPolicy.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainStatus.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainStatus.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainStatus.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainStatus.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainStatusFlags.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainStatusFlags.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainStatusFlags.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainStatusFlags.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainTrustMode.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainTrustMode.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainTrustMode.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainTrustMode.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ContentType.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ContentType.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ContentType.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ContentType.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs similarity index 90% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs index 70a802a0135388..5f7de6941e23e7 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs @@ -1,16 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.IO; -using System.Text; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.InteropServices; - -using Internal.Cryptography; -using Internal.Cryptography.Pal; - namespace System.Security.Cryptography.X509Certificates { public sealed class X509EnhancedKeyUsageExtension : X509Extension diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Extension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Extension.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Extension.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Extension.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ExtensionCollection.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ExtensionCollection.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ExtensionCollection.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ExtensionCollection.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ExtensionEnumerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ExtensionEnumerator.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ExtensionEnumerator.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ExtensionEnumerator.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509FindType.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509FindType.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509FindType.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509FindType.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509IncludeOption.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509IncludeOption.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509IncludeOption.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509IncludeOption.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509KeyStorageFlags.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyStorageFlags.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509KeyStorageFlags.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyStorageFlags.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs similarity index 86% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs index 6f844d21b86b89..631b55139a561c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs @@ -1,16 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.IO; -using System.Text; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.InteropServices; - -using Internal.Cryptography; -using Internal.Cryptography.Pal; - namespace System.Security.Cryptography.X509Certificates { public sealed class X509KeyUsageExtension : X509Extension diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509KeyUsageFlags.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyUsageFlags.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509KeyUsageFlags.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyUsageFlags.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509NameType.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509NameType.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509NameType.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509NameType.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/X509Pal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Android.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/X509Pal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Android.cs index 370127735235b7..e1cc094ff5c835 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Android/X509Pal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Android.cs @@ -7,16 +7,14 @@ using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed partial class X509Pal + internal static partial class X509Pal { - public static IX509Pal Instance = new AndroidX509Pal(); - - private X509Pal() + private static partial IX509Pal BuildSingleton() { + return new AndroidX509Pal(); } private sealed partial class AndroidX509Pal : ManagedX509ExtensionProcessor, IX509Pal diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/X509Pal.ECKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Apple.ECKey.cs similarity index 88% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/X509Pal.ECKey.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Apple.ECKey.cs index d4295ada4b50dd..df21ef3ceaa585 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/X509Pal.ECKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Apple.ECKey.cs @@ -1,19 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Buffers; -using System.Diagnostics; -using System.Formats.Asn1; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.Asn1; -using System.Security.Cryptography.Asn1.Pkcs12; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed partial class X509Pal + internal partial class X509Pal { private sealed partial class AppleX509Pal : ManagedX509ExtensionProcessor, IX509Pal { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/X509Pal.X500Name.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Apple.X500Name.cs similarity index 86% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/X509Pal.X500Name.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Apple.X500Name.cs index 0bcaae2ab5fc5a..b5fe1db6575335 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/X509Pal.X500Name.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Apple.X500Name.cs @@ -1,13 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; - -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed partial class X509Pal + internal partial class X509Pal { private sealed partial class AppleX509Pal : ManagedX509ExtensionProcessor, IX509Pal { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.NotSupported.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.NotSupported.cs new file mode 100644 index 00000000000000..fbaf9e13b57bfe --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.NotSupported.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.X509Certificates +{ + internal static partial class X509Pal + { + private static partial IX509Pal BuildSingleton() + { + throw new PlatformNotSupportedException(SR.SystemSecurityCryptographyX509Certificates_PlatformNotSupported); + } + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X509Pal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.OpenSsl.cs similarity index 57% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X509Pal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.OpenSsl.cs index 74275401d68b83..28cbc90916ddf4 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X509Pal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.OpenSsl.cs @@ -1,14 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal sealed partial class X509Pal { - public static IX509Pal Instance = new OpenSslX509Encoder(); - - private X509Pal() + private static partial IX509Pal BuildSingleton() { + return new OpenSslX509Encoder(); } } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.CustomExtensions.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.CustomExtensions.cs similarity index 97% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.CustomExtensions.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.CustomExtensions.cs index 677fb54ac35b1a..c990d994009686 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.CustomExtensions.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.CustomExtensions.cs @@ -1,20 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Text; using System.Diagnostics; -using System.Globalization; -using System.Collections.Generic; using System.Runtime.InteropServices; - using Internal.Cryptography; -using Internal.Cryptography.Pal.Native; - -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { /// /// A singleton class that encapsulates the native implementation of various X509 services. (Implementing this as a singleton makes it diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.GetCertContentType.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.GetCertContentType.cs similarity index 94% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.GetCertContentType.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.GetCertContentType.cs index ff26212b623a80..c60079458b7136 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.GetCertContentType.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.GetCertContentType.cs @@ -1,19 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Text; -using System.Diagnostics; -using System.Globalization; using System.Runtime.InteropServices; - using Internal.Cryptography; -using Internal.Cryptography.Pal.Native; - -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { /// /// A singleton class that encapsulates the native implementation of various X509 services. (Implementing this as a singleton makes it diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.PublicKey.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.PublicKey.cs index 13dcd63f4f91f7..20ac22206124be 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.PublicKey.cs @@ -1,20 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography.Pal.Native; -using Microsoft.Win32.SafeHandles; -using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -using System.Security.Cryptography; +using Internal.Cryptography; +using Microsoft.Win32.SafeHandles; using NTSTATUS = Interop.BCrypt.NTSTATUS; using SafeBCryptKeyHandle = Microsoft.Win32.SafeHandles.SafeBCryptKeyHandle; using static Interop.Crypt32; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { /// /// A singleton class that encapsulates the native implementation of various X509 services. (Implementing this as a singleton makes it diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.X500DistinguishedName.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.X500DistinguishedName.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.X500DistinguishedName.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.X500DistinguishedName.cs index 09341dca638bbb..7339a32cf6930c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.X500DistinguishedName.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.X500DistinguishedName.cs @@ -1,13 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Security.Cryptography.X509Certificates; -using Internal.Cryptography.Pal.Native; +using Internal.Cryptography; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { /// /// A singleton class that encapsulates the native implementation of various X509 services. (Implementing this as a singleton makes it diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.cs new file mode 100644 index 00000000000000..a2c9fb1636df29 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.Windows.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.X509Certificates +{ + internal partial class X509Pal : IX509Pal + { + private static partial IX509Pal BuildSingleton() + { + return new X509Pal(); + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.cs new file mode 100644 index 00000000000000..8060dc75972bc6 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.X509Certificates +{ + internal partial class X509Pal + { + internal static IX509Pal Instance { get; } = BuildSingleton(); + + private static partial IX509Pal BuildSingleton(); + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/X509Pal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.iOS.cs similarity index 90% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/X509Pal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.iOS.cs index 283bd38c066dce..f9ff5f38b87af5 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.iOS/X509Pal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.iOS.cs @@ -1,22 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Buffers; using System.Diagnostics; -using System.Text; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed partial class X509Pal + internal static partial class X509Pal { - public static IX509Pal Instance = new AppleX509Pal(); - - private X509Pal() + private static partial IX509Pal BuildSingleton() { + return new AppleX509Pal(); } private sealed partial class AppleX509Pal : ManagedX509ExtensionProcessor, IX509Pal diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/X509Pal.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.macOS.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/X509Pal.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.macOS.cs index 2b654b2b3b9c2f..5d60633639064f 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.OSX/X509Pal.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Pal.macOS.cs @@ -1,24 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; using System.Diagnostics; using System.Formats.Asn1; -using System.Security.Cryptography; using System.Security.Cryptography.Apple; using System.Security.Cryptography.Asn1; using System.Security.Cryptography.Asn1.Pkcs12; -using System.Security.Cryptography.X509Certificates; -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { - internal sealed partial class X509Pal + internal static partial class X509Pal { - public static IX509Pal Instance = new AppleX509Pal(); - - private X509Pal() + private static partial IX509Pal BuildSingleton() { + return new AppleX509Pal(); } private sealed partial class AppleX509Pal : ManagedX509ExtensionProcessor, IX509Pal diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X509Persistence.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Persistence.cs similarity index 89% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X509Persistence.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Persistence.cs index 5eb56054ab11a1..c8818105cc2f28 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X509Persistence.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Persistence.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Internal.Cryptography.Pal +namespace System.Security.Cryptography.X509Certificates { internal static class X509Persistence { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509RevocationFlag.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509RevocationFlag.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509RevocationFlag.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509RevocationFlag.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509RevocationMode.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509RevocationMode.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509RevocationMode.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509RevocationMode.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SignatureGenerator.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509SignatureGenerator.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SignatureGenerator.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Store.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Store.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Store.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Store.cs index d16b59b325a9af..d97ead09424f14 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Store.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Store.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography.Pal; using System.Diagnostics; -using System.Globalization; namespace System.Security.Cryptography.X509Certificates { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs similarity index 98% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs index aaeefd3eeee46b..1d239cf58fee57 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography; -using Internal.Cryptography.Pal; namespace System.Security.Cryptography.X509Certificates { @@ -79,7 +78,7 @@ private static byte[] EncodeExtension(string subjectKeyIdentifier) if (subjectKeyIdentifier == null) throw new ArgumentNullException(nameof(subjectKeyIdentifier)); - byte[] subjectKeyIdentifiedBytes = subjectKeyIdentifier.DecodeHexString(); + byte[] subjectKeyIdentifiedBytes = subjectKeyIdentifier.LaxDecodeHexString(); return EncodeExtension(subjectKeyIdentifiedBytes); } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierHashAlgorithm.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierHashAlgorithm.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierHashAlgorithm.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierHashAlgorithm.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509VerificationFlags.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509VerificationFlags.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509VerificationFlags.cs rename to src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509VerificationFlags.cs diff --git a/src/libraries/System.Security.Principal/System.Security.Principal.sln b/src/libraries/System.Security.Principal/System.Security.Principal.sln index 269c8867d3b4a8..6dc3723dade565 100644 --- a/src/libraries/System.Security.Principal/System.Security.Principal.sln +++ b/src/libraries/System.Security.Principal/System.Security.Principal.sln @@ -1,7 +1,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "..\..\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj", "{45602EBE-1508-43A8-A398-1B92BD243557}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{9C81AA4B-B9FB-42CC-9BEF-D3B3768BC0C3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{9C81AA4B-B9FB-42CC-9BEF-D3B3768BC0C3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.DllImportGenerator", "..\System.Runtime.InteropServices\gen\DllImportGenerator\DllImportGenerator.csproj", "{858D214B-C022-4CD7-B3DC-0DF7BF4C01D0}" EndProject diff --git a/src/libraries/System.ServiceProcess.ServiceController/NuGet.config b/src/libraries/System.ServiceProcess.ServiceController/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.ServiceProcess.ServiceController/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System.ServiceProcess.ServiceController.csproj b/src/libraries/System.ServiceProcess.ServiceController/src/System.ServiceProcess.ServiceController.csproj index fac46aed04ba2c..4ee87fe36d3297 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System.ServiceProcess.ServiceController.csproj +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System.ServiceProcess.ServiceController.csproj @@ -1,7 +1,7 @@ true - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0-windows;netstandard2.0;$(NetFrameworkMinimum) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) $(NoWarn);CA2249 enable true diff --git a/src/libraries/System.Text.Encoding.CodePages/NuGet.config b/src/libraries/System.Text.Encoding.CodePages/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Text.Encoding.CodePages/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj b/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj index 061c30752e435f..094f9c43ec7db1 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj +++ b/src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj @@ -2,7 +2,7 @@ true enable - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0-windows;netstandard2.0;$(NetFrameworkMinimum) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true true true diff --git a/src/libraries/System.Text.Encoding.Extensions/System.Text.Encoding.Extensions.sln b/src/libraries/System.Text.Encoding.Extensions/System.Text.Encoding.Extensions.sln index 5b392611a1cd95..b9b1172d81c6cf 100644 --- a/src/libraries/System.Text.Encoding.Extensions/System.Text.Encoding.Extensions.sln +++ b/src/libraries/System.Text.Encoding.Extensions/System.Text.Encoding.Extensions.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{CC6D3524-D6C8-468B-B908-CE746C1DB175}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{0FB90CF0-6B17-4FAB-A737-0532B5BCAADB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{0FB90CF0-6B17-4FAB-A737-0532B5BCAADB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{7101801F-0F2D-4D30-BD45-99F0A824EBEC}" EndProject diff --git a/src/libraries/System.Text.Encoding/System.Text.Encoding.sln b/src/libraries/System.Text.Encoding/System.Text.Encoding.sln index 8a936eb8939556..f2e0348d71d1df 100644 --- a/src/libraries/System.Text.Encoding/System.Text.Encoding.sln +++ b/src/libraries/System.Text.Encoding/System.Text.Encoding.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.Pipelines", "..\S EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.IO.Pipelines", "..\System.IO.Pipelines\src\System.IO.Pipelines.csproj", "{530C65D8-0440-4AF2-8975-F03EFF573195}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{604213DB-0DCD-41AC-A244-502BDBA57CB5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{604213DB-0DCD-41AC-A244-502BDBA57CB5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{E8313B01-55A4-48E6-964A-298512B0FB7B}" EndProject diff --git a/src/libraries/System.Text.Json/gen/Reflection/CustomAttributeDataWrapper.cs b/src/libraries/System.Text.Json/gen/Reflection/CustomAttributeDataWrapper.cs index 58354168b719f6..3aeaf9e186bf7f 100644 --- a/src/libraries/System.Text.Json/gen/Reflection/CustomAttributeDataWrapper.cs +++ b/src/libraries/System.Text.Json/gen/Reflection/CustomAttributeDataWrapper.cs @@ -15,7 +15,7 @@ public CustomAttributeDataWrapper(AttributeData a, MetadataLoadContextInternal m var namedArguments = new List(); foreach (KeyValuePair na in a.NamedArguments) { - var member = a.AttributeClass!.GetMembers(na.Key).First(); + var member = a.AttributeClass.BaseTypes().SelectMany(t => t.GetMembers(na.Key)).First(); MemberInfo memberInfo = member is IPropertySymbol ? new PropertyInfoWrapper((IPropertySymbol)member, metadataLoadContext) diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs index c01499f7fef3e3..a21ab179cc8eda 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs @@ -47,6 +47,8 @@ public interface ITestContext public JsonTypeInfo ClassWithBadCustomConverter { get; } public JsonTypeInfo StructWithBadCustomConverter { get; } public JsonTypeInfo NullablePersonStruct { get; } + public JsonTypeInfo TypeWithValidationAttributes { get; } + public JsonTypeInfo TypeWithDerivedAttribute { get; } } internal partial class JsonContext : JsonSerializerContext diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs index 57abdf04808a0c..092d6110170739 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs @@ -41,6 +41,8 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(ClassWithBadCustomConverter))] [JsonSerializable(typeof(StructWithBadCustomConverter))] [JsonSerializable(typeof(PersonStruct?))] + [JsonSerializable(typeof(TypeWithValidationAttributes))] + [JsonSerializable(typeof(TypeWithDerivedAttribute))] internal partial class MetadataAndSerializationContext : JsonSerializerContext, ITestContext { public JsonSourceGenerationMode JsonSourceGenerationMode => JsonSourceGenerationMode.Default; @@ -88,6 +90,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Throws(() => MetadataAndSerializationContext.Default.StructWithBadCustomConverter); Assert.Null(MetadataAndSerializationContext.Default.NullablePersonStruct.SerializeHandler); Assert.NotNull(MetadataAndSerializationContext.Default.PersonStruct.SerializeHandler); + Assert.NotNull(MetadataAndSerializationContext.Default.TypeWithValidationAttributes.SerializeHandler); + Assert.NotNull(MetadataAndSerializationContext.Default.TypeWithDerivedAttribute.SerializeHandler); } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs index d0c3023b41ae9f..0f9df146d25450 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs @@ -40,6 +40,8 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(ClassWithBadCustomConverter), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(StructWithBadCustomConverter), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(PersonStruct?), GenerationMode = JsonSourceGenerationMode.Metadata)] + [JsonSerializable(typeof(TypeWithValidationAttributes), GenerationMode = JsonSourceGenerationMode.Metadata)] + [JsonSerializable(typeof(TypeWithDerivedAttribute), GenerationMode = JsonSourceGenerationMode.Metadata)] internal partial class MetadataWithPerTypeAttributeContext : JsonSerializerContext, ITestContext { public JsonSourceGenerationMode JsonSourceGenerationMode => JsonSourceGenerationMode.Metadata; @@ -86,6 +88,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Throws(() => MetadataWithPerTypeAttributeContext.Default.StructWithBadCustomConverter.SerializeHandler); Assert.Null(MetadataWithPerTypeAttributeContext.Default.NullablePersonStruct.SerializeHandler); Assert.Null(MetadataWithPerTypeAttributeContext.Default.PersonStruct.SerializeHandler); + Assert.Null(MetadataWithPerTypeAttributeContext.Default.TypeWithValidationAttributes.SerializeHandler); + Assert.Null(MetadataWithPerTypeAttributeContext.Default.TypeWithDerivedAttribute.SerializeHandler); } } @@ -124,6 +128,8 @@ public override void EnsureFastPathGeneratedAsExpected() [JsonSerializable(typeof(ClassWithBadCustomConverter))] [JsonSerializable(typeof(StructWithBadCustomConverter))] [JsonSerializable(typeof(PersonStruct?))] + [JsonSerializable(typeof(TypeWithValidationAttributes))] + [JsonSerializable(typeof(TypeWithDerivedAttribute))] internal partial class MetadataContext : JsonSerializerContext, ITestContext { public JsonSourceGenerationMode JsonSourceGenerationMode => JsonSourceGenerationMode.Metadata; @@ -193,6 +199,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Throws(() => MetadataContext.Default.StructWithBadCustomConverter.SerializeHandler); Assert.Null(MetadataContext.Default.NullablePersonStruct.SerializeHandler); Assert.Null(MetadataContext.Default.PersonStruct.SerializeHandler); + Assert.Null(MetadataContext.Default.TypeWithValidationAttributes.SerializeHandler); + Assert.Null(MetadataContext.Default.TypeWithDerivedAttribute.SerializeHandler); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs index d5475515699359..1a1dd3a3906ddc 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs @@ -41,6 +41,8 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(ClassWithBadCustomConverter), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(StructWithBadCustomConverter), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(PersonStruct?), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(TypeWithValidationAttributes), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(TypeWithDerivedAttribute), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] internal partial class MixedModeContext : JsonSerializerContext, ITestContext { public JsonSourceGenerationMode JsonSourceGenerationMode => JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization; @@ -88,6 +90,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Throws(() => MixedModeContext.Default.StructWithBadCustomConverter.SerializeHandler); Assert.Null(MixedModeContext.Default.NullablePersonStruct.SerializeHandler); Assert.NotNull(MixedModeContext.Default.PersonStruct.SerializeHandler); + Assert.NotNull(MixedModeContext.Default.TypeWithValidationAttributes.SerializeHandler); + Assert.NotNull(MixedModeContext.Default.TypeWithDerivedAttribute.SerializeHandler); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs index 1cb9cb56bbf9fa..8c384fb7d98fdc 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs @@ -882,5 +882,44 @@ public virtual void NullableStruct() Assert.Equal("Jane", person.Value.FirstName); Assert.Equal("Doe", person.Value.LastName); } + + [Fact] + public void TypeWithValidationAttributes() + { + var instance = new TypeWithValidationAttributes { Name = "Test Name", Email = "email@test.com" }; + + string json = JsonSerializer.Serialize(instance, DefaultContext.TypeWithValidationAttributes); + JsonTestHelper.AssertJsonEqual(@"{""Name"":""Test Name"",""Email"":""email@test.com""}", json); + if (DefaultContext.JsonSourceGenerationMode == JsonSourceGenerationMode.Serialization) + { + // Deserialization not supported in fast path serialization only mode + Assert.Throws(() => JsonSerializer.Deserialize(json, DefaultContext.TypeWithValidationAttributes)); + } + else + { + instance = JsonSerializer.Deserialize(json, DefaultContext.TypeWithValidationAttributes); + Assert.Equal("Test Name", instance.Name); + Assert.Equal("email@test.com", instance.Email); + } + } + + [Fact] + public void TypeWithDerivedAttribute() + { + var instance = new TypeWithDerivedAttribute(); + + string json = JsonSerializer.Serialize(instance, DefaultContext.TypeWithDerivedAttribute); + JsonTestHelper.AssertJsonEqual(@"{}", json); + if (DefaultContext.JsonSourceGenerationMode == JsonSourceGenerationMode.Serialization) + { + // Deserialization not supported in fast path serialization only mode + Assert.Throws(() => JsonSerializer.Deserialize(json, DefaultContext.TypeWithDerivedAttribute)); + } + else + { + instance = JsonSerializer.Deserialize(json, DefaultContext.TypeWithDerivedAttribute); + Assert.NotNull(instance); + } + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs index b51ba070be1885..765f8a883454d6 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs @@ -41,6 +41,8 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(ClassWithBadCustomConverter))] [JsonSerializable(typeof(StructWithBadCustomConverter))] [JsonSerializable(typeof(PersonStruct?))] + [JsonSerializable(typeof(TypeWithValidationAttributes))] + [JsonSerializable(typeof(TypeWithDerivedAttribute))] internal partial class SerializationContext : JsonSerializerContext, ITestContext { public JsonSourceGenerationMode JsonSourceGenerationMode => JsonSourceGenerationMode.Serialization; @@ -80,6 +82,8 @@ internal partial class SerializationContext : JsonSerializerContext, ITestContex [JsonSerializable(typeof(ClassWithBadCustomConverter), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(StructWithBadCustomConverter), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(PersonStruct?), GenerationMode = JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(TypeWithValidationAttributes), GenerationMode = JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(TypeWithDerivedAttribute), GenerationMode = JsonSourceGenerationMode.Serialization)] internal partial class SerializationWithPerTypeAttributeContext : JsonSerializerContext, ITestContext { public JsonSourceGenerationMode JsonSourceGenerationMode => JsonSourceGenerationMode.Serialization; @@ -120,6 +124,8 @@ internal partial class SerializationWithPerTypeAttributeContext : JsonSerializer [JsonSerializable(typeof(ClassWithBadCustomConverter), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(StructWithBadCustomConverter), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(PersonStruct?), GenerationMode = JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(TypeWithValidationAttributes), GenerationMode = JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(TypeWithDerivedAttribute), GenerationMode = JsonSourceGenerationMode.Serialization)] internal partial class SerializationContextWithCamelCase : JsonSerializerContext, ITestContext { public JsonSourceGenerationMode JsonSourceGenerationMode => JsonSourceGenerationMode.Serialization; @@ -169,6 +175,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Throws(() => SerializationContext.Default.StructWithBadCustomConverter.SerializeHandler); Assert.Null(SerializationContext.Default.NullablePersonStruct.SerializeHandler); Assert.NotNull(SerializationContext.Default.PersonStruct.SerializeHandler); + Assert.NotNull(SerializationContext.Default.TypeWithValidationAttributes.SerializeHandler); + Assert.NotNull(SerializationContext.Default.TypeWithDerivedAttribute.SerializeHandler); } [Fact] @@ -492,6 +500,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Throws(() => SerializationWithPerTypeAttributeContext.Default.StructWithBadCustomConverter.SerializeHandler); Assert.Null(SerializationWithPerTypeAttributeContext.Default.NullablePersonStruct.SerializeHandler); Assert.NotNull(SerializationWithPerTypeAttributeContext.Default.PersonStruct.SerializeHandler); + Assert.NotNull(SerializationWithPerTypeAttributeContext.Default.TypeWithValidationAttributes.SerializeHandler); + Assert.NotNull(SerializationWithPerTypeAttributeContext.Default.TypeWithDerivedAttribute.SerializeHandler); } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs index 29e76ec6e15605..a9124235863371 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs @@ -158,4 +158,26 @@ public struct PersonStruct public string FirstName { get; set; } public string LastName { get; set; } } + + public class TypeWithValidationAttributes + { + [ComponentModel.DataAnnotations.Required(ErrorMessage = "Name is required")] + [ComponentModel.DataAnnotations.StringLength(100, ErrorMessage = "Name must not be longer than 100 characters")] + public string Name { get; set; } + + [ComponentModel.DataAnnotations.Required] + public string Email { get; set; } + } + + public class BaseAttribute : Attribute + { + public string TestProperty { get; set; } + } + + public class DerivedAttribute : BaseAttribute + { } + + [Derived(TestProperty = "Test")] + public class TypeWithDerivedAttribute + { } } diff --git a/src/libraries/System.Threading.AccessControl/NuGet.config b/src/libraries/System.Threading.AccessControl/NuGet.config deleted file mode 100644 index a66b7f9b013241..00000000000000 --- a/src/libraries/System.Threading.AccessControl/NuGet.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj b/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj index 577a87e8461572..572fbfcb4e6cdb 100644 --- a/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj +++ b/src/libraries/System.Threading.AccessControl/src/System.Threading.AccessControl.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0-windows;netstandard2.0;$(NetFrameworkMinimum) + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true enable true diff --git a/src/libraries/System.Threading.Overlapped/System.Threading.Overlapped.sln b/src/libraries/System.Threading.Overlapped/System.Threading.Overlapped.sln index 255eb1f50e7fad..c90bcba9a1340f 100644 --- a/src/libraries/System.Threading.Overlapped/System.Threading.Overlapped.sln +++ b/src/libraries/System.Threading.Overlapped/System.Threading.Overlapped.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{A4B84F3E-9C18-4CF7-8CA8-9F4AA4A1634F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{8BAAF37B-C3C1-4DED-A89A-5513AE866360}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{8BAAF37B-C3C1-4DED-A89A-5513AE866360}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{CE4C0C71-A94E-42B0-B6EA-46710F09B04E}" EndProject diff --git a/src/libraries/System.Threading.Tasks.Extensions/System.Threading.Tasks.Extensions.sln b/src/libraries/System.Threading.Tasks.Extensions/System.Threading.Tasks.Extensions.sln index e84ea1b6d1e07d..701516daced0a3 100644 --- a/src/libraries/System.Threading.Tasks.Extensions/System.Threading.Tasks.Extensions.sln +++ b/src/libraries/System.Threading.Tasks.Extensions/System.Threading.Tasks.Extensions.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{FFB40D04-17A5-4F9B-BD47-994E5616ABD9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{5650548E-4175-4BD3-B23C-11FCB86AD2EF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{5650548E-4175-4BD3-B23C-11FCB86AD2EF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{ECCFA0AE-EDD8-4CA1-91A3-D03A2316B9EA}" EndProject diff --git a/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln b/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln index 927f7984d66093..255f670ab54e38 100644 --- a/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln +++ b/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{A0477DE6-08C7-4793-A8B6-9974F2675AC7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{A0477DE6-08C7-4793-A8B6-9974F2675AC7}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{EAF13385-99A5-463C-9343-CE14241DD5A1}" EndProject diff --git a/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs b/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs index a140578160d97f..fa01ab6b75c892 100644 --- a/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs +++ b/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs @@ -110,6 +110,14 @@ public void WaitOnAsyncWaitHandleTechnique(bool hasReturnType) Assert.False(asyncResult.CompletedSynchronously, "Should not have completed synchronously."); } + [Fact] + public void AsyncWaitHandle_DisposeHandleThenCompleteTask_Succeeds() + { + var tcs = new TaskCompletionSource(); + ((IAsyncResult)tcs.Task).AsyncWaitHandle.Dispose(); + tcs.SetResult(); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [OuterLoop] [InlineData(true)] diff --git a/src/libraries/System.Threading.Thread/System.Threading.Thread.sln b/src/libraries/System.Threading.Thread/System.Threading.Thread.sln index 57158f37a4dcae..683603243ab9a9 100644 --- a/src/libraries/System.Threading.Thread/System.Threading.Thread.sln +++ b/src/libraries/System.Threading.Thread/System.Threading.Thread.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{BF6A7CA7-DDF9-44D4-AD00-D807765663F9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{566DB44F-5EF1-4421-B09A-F202E76935A9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{566DB44F-5EF1-4421-B09A-F202E76935A9}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{891D5917-09B5-4DEF-B9E0-7CB8866B74C9}" EndProject diff --git a/src/libraries/System.Threading.ThreadPool/System.Threading.ThreadPool.sln b/src/libraries/System.Threading.ThreadPool/System.Threading.ThreadPool.sln index 0b15b10073406a..8617f00f752981 100644 --- a/src/libraries/System.Threading.ThreadPool/System.Threading.ThreadPool.sln +++ b/src/libraries/System.Threading.ThreadPool/System.Threading.ThreadPool.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{CD477FC8-AF27-46A2-A451-4A2D4C11600D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{54E0AB0F-EB35-49AB-9A38-7C09FD7EC373}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{54E0AB0F-EB35-49AB-9A38-7C09FD7EC373}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{969E8154-9D99-49CB-B435-F5E4936DDE58}" EndProject diff --git a/src/libraries/System.Threading.Timer/System.Threading.Timer.sln b/src/libraries/System.Threading.Timer/System.Threading.Timer.sln index 82b2922aee67bf..930ddaeeefcc4d 100644 --- a/src/libraries/System.Threading.Timer/System.Threading.Timer.sln +++ b/src/libraries/System.Threading.Timer/System.Threading.Timer.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{567E9CC8-5751-4786-BCC6-C2A6C38044DF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{629ACB77-0503-4501-8AD5-E574E3F498E6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{629ACB77-0503-4501-8AD5-E574E3F498E6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{DD59BC62-51E9-43BF-BAE2-B5B6443B5C4C}" EndProject diff --git a/src/libraries/System.Threading/System.Threading.sln b/src/libraries/System.Threading/System.Threading.sln index cc8b0b06d5ebd1..fcd6d5506633e7 100644 --- a/src/libraries/System.Threading/System.Threading.sln +++ b/src/libraries/System.Threading/System.Threading.sln @@ -3,7 +3,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{387778C0-0405-4FE2-9D85-034254EAAD46}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{AB7F1F45-5C20-40C7-B6DA-192B37012DD8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{AB7F1F45-5C20-40C7-B6DA-192B37012DD8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\ref\System.Runtime.CompilerServices.Unsafe.csproj", "{120AAA2F-6798-4C03-BFEB-656466A78B04}" EndProject diff --git a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj index 6e587b9c50f8f8..2266de2c9476d6 100644 --- a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj +++ b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj @@ -105,4 +105,7 @@ System.Security.Cryptography.X509Certificates.X509SelectionFlag + + + diff --git a/src/libraries/illink-oob.targets b/src/libraries/illink-oob.targets index 4775c20bd93016..d609c1d47bdf26 100644 --- a/src/libraries/illink-oob.targets +++ b/src/libraries/illink-oob.targets @@ -4,7 +4,8 @@ DependsOnTargets="PrepareForAssembliesTrim"> - $([MSBuild]::NormalizePath('$(ILLinkTrimAssemblyArtifactsRootDir)', 'trimmed-oobs')) + $([MSBuild]::NormalizeDirectory('$(ILLinkTrimAssemblyArtifactsRootDir)', 'trimmed-oobs')) + $(IntermediateOutputPath)oob-linker-$(TargetOS)-$(TargetArchitecture)-marker.txt @@ -24,7 +25,7 @@ @@ -56,7 +57,7 @@ AfterTargets="Build" DependsOnTargets="GetOOBAssembliesToTrim;PrepareForAssembliesTrim" Inputs="$(ILLinkTasksAssembly);@(OOBAssemblyToTrim);@(OOBAssemblyReference);@(OOBLibrarySuppressionsXml)" - Outputs="@(OOBLibraryTrimmed)"> + Outputs="$(OOBAssembliesMarkerFile)"> @@ -73,6 +74,11 @@ ToolExe="$(_DotNetHostFileName)" ToolPath="$(_DotNetHostDirectory)" /> + + + + diff --git a/src/libraries/illink-sharedframework.targets b/src/libraries/illink-sharedframework.targets index 0cc83fb1c74677..8641657b9f58d0 100644 --- a/src/libraries/illink-sharedframework.targets +++ b/src/libraries/illink-sharedframework.targets @@ -4,7 +4,8 @@ DependsOnTargets="PrepareForAssembliesTrim"> - $([MSBuild]::NormalizePath('$(ILLinkTrimAssemblyArtifactsRootDir)', 'trimmed-runtimepack')) + $([MSBuild]::NormalizeDirectory('$(ILLinkTrimAssemblyArtifactsRootDir)', 'trimmed-runtimepack')) + $(IntermediateOutputPath)sfx-linker-$(TargetOS)-$(TargetArchitecture)-marker.txt @@ -28,7 +29,7 @@ AfterTargets="Build" DependsOnTargets="GetSharedFrameworkAssembliesToTrim;PrepareForAssembliesTrim" Inputs="$(ILLinkTasksAssembly);@(SharedFrameworkAssemblyToTrim);@(SharedFrameworkSuppressionsXml)" - Outputs="@(SharedFrameworkAssemblyTrimmed)"> + Outputs="$(SharedFrameworkAssembliesMarkerFile)"> @@ -55,6 +56,11 @@ ToolExe="$(_DotNetHostFileName)" ToolPath="$(_DotNetHostDirectory)" /> + + + + diff --git a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt index f408c36427e63e..a49a465752eedb 100644 --- a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt +++ b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt @@ -75,9 +75,11 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. +CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Security.Cryptography.X509Certificates.PublicKey.GetDSAPublicKey()' changed from '[UnsupportedOSPlatformAttribute("ios")]' in the contract to '[UnsupportedOSPlatformAttribute("browser")]' in the implementation. Compat issues with assembly System: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. +CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Security.Cryptography.X509Certificates.PublicKey.GetDSAPublicKey()' changed from '[UnsupportedOSPlatformAttribute("ios")]' in the contract to '[UnsupportedOSPlatformAttribute("browser")]' in the implementation. Compat issues with assembly System.Core: CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.Aes' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECCurve' in the contract but not the implementation. @@ -138,4 +140,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. -Total Issues: 132 +Compat issues with assembly System.Security.Cryptography.X509Certificates: +CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Security.Cryptography.X509Certificates.PublicKey.GetDSAPublicKey()' changed from '[UnsupportedOSPlatformAttribute("ios")]' in the contract to '[UnsupportedOSPlatformAttribute("browser")]' in the implementation. +Total Issues: 135 diff --git a/src/libraries/slngen.proj b/src/libraries/slngen.proj index f6252926847630..c517303434362b 100644 --- a/src/libraries/slngen.proj +++ b/src/libraries/slngen.proj @@ -1,12 +1,10 @@ $(RepositoryEngineeringDir)slngen.template.proj - $(RepositoryEngineeringDir)slngen.nuget.config @@ -30,37 +28,6 @@ - - - - - - - $([System.IO.File]::ReadAllText('%(SolutionFile.Identity)')) - - true - - - - - - - - - - - - - @@ -68,27 +35,4 @@ NuGetConfigFilePath="%(RelativeDir)NuGet.config" /> - - - - - $([System.IO.File]::ReadAllText('%(SourceProject.Identity)')) - - $([System.Text.RegularExpressions.Regex]::Match($(ProjectFileContent), '<TargetFrameworks>(.+%3F)<\/TargetFrameworks>')) - $(ProjectFileTargetFrameworks.Replace('<TargetFrameworks>', '')) - $(ProjectFileTargetFrameworks.Replace('</TargetFrameworks>', '')) - - $([System.Text.RegularExpressions.Regex]::Replace('$(ProjectFileTargetFrameworks)', '(-[^;]+)', '')) - - $([System.Text.RegularExpressions.Regex]::IsMatch('$(ProjectFileTargetFrameworks);', '(netstandard.+|net4.+)(?=.*;\1;)')) - - - - - - diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 2e5554df5bc5bc..bc7da23c21ab40 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -25,9 +25,9 @@ - + + @@ -38,6 +38,10 @@ Roslyn4.0.Tests.csproj" /> + + + + @@ -47,6 +51,11 @@ Roslyn4.0.Tests.csproj" /> + + + + + @@ -277,6 +286,16 @@ Roslyn4.0.Tests.csproj" /> + + + + + + + + + + diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 909e1f72c19dca..348b5e9960bab1 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -490,19 +490,23 @@ if(GCC) # We rely on signed overflow to behave append("-fwrapv" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - set(WARNINGS "-Wall -Wunused -Wmissing-declarations -Wpointer-arith -Wno-cast-qual -Wwrite-strings -Wno-switch -Wno-switch-enum -Wno-unused-value -Wno-attributes -Wmissing-prototypes -Wstrict-prototypes -Wnested-externs -Wno-format-zero-length -Wno-unused-function") + set(WARNINGS "-Wall -Wunused -Wmissing-declarations -Wpointer-arith -Wno-cast-qual -Wwrite-strings -Wno-switch -Wno-switch-enum -Wno-unused-value -Wno-attributes -Wno-format-zero-length -Wno-unused-function") + set(WARNINGS_C "-Wmissing-prototypes -Wstrict-prototypes -Wnested-externs") if (CMAKE_C_COMPILER_ID MATCHES "Clang") set(WARNINGS "${WARNINGS} -Qunused-arguments -Wno-tautological-compare -Wno-parentheses-equality -Wno-self-assign -Wno-return-stack-address -Wno-constant-logical-operand -Wno-zero-length-array") endif() + set(WERROR "-Werror=return-type") + set(WERROR_C "-Werror=implicit-function-declaration") + check_c_compiler_flag("-Werror=incompatible-pointer-types" WERROR_INCOMPATIBLE_POINTER_TYPES) if(WERROR_INCOMPATIBLE_POINTER_TYPES) - set(WERROR "-Werror=incompatible-pointer-types") + set(WERROR_C "${WERROR_C} -Werror=incompatible-pointer-types") endif() - set(WERROR "-Werror=return-type -Werror-implicit-function-declaration") - append("${WARNINGS} ${WERROR}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + append("${WARNINGS} ${WARNINGS_C} ${WERROR} ${WERROR_C}" CMAKE_C_FLAGS) + append("${WARNINGS} ${WERROR}" CMAKE_CXX_FLAGS) set(MONO_ZERO_LEN_ARRAY 0) diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index d952686ac56b89..4e7cecac1a25a8 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -310,7 +310,7 @@ - + diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.sln b/src/mono/System.Private.CoreLib/System.Private.CoreLib.sln index e350a850ff1665..d23b2e284f5bce 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.sln +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.sln @@ -6,7 +6,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "S EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "System.Private.CoreLib.Shared", "..\..\libraries\System.Private.CoreLib\src\System.Private.CoreLib.Shared.shproj", "{845C8B26-350B-4E63-BD11-2C8150444E28}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\..\libraries\System.Private.CoreLib\generators\System.Private.CoreLib.Generators.csproj", "{A4CD9C83-5937-46B7-A1F2-1990F5B938E7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib.Generators", "..\..\libraries\System.Private.CoreLib\gen\System.Private.CoreLib.Generators.csproj", "{A4CD9C83-5937-46B7-A1F2-1990F5B938E7}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution diff --git a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs index 5a7bab2f739863..cb1bd0d52d26b5 100644 --- a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs @@ -167,6 +167,7 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati Type src_type = sourceArray.GetType().GetElementType()!; Type dst_type = destinationArray.GetType().GetElementType()!; + Type dst_elem_type = dst_type; bool dst_type_vt = dst_type.IsValueType && Nullable.GetUnderlyingType(dst_type) == null; bool src_is_enum = src_type.IsEnum; @@ -199,12 +200,9 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati { object srcval = sourceArray.GetValueImpl(source_pos + i); - if (!src_type.IsValueType && dst_is_enum) + if (dst_type_vt && (srcval == null || (src_type == typeof(object) && !dst_elem_type.IsAssignableFrom (srcval.GetType())))) throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement); - if (dst_type_vt && (srcval == null || (src_type == typeof(object) && srcval.GetType() != dst_type))) - throw new InvalidCastException(); - try { destinationArray.SetValueRelaxedImpl(srcval, dest_pos + i); diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index d558691594751e..8221e93c36bf66 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -414,7 +414,7 @@ static gboolean buffer_replies; DebuggerTlsData *tls; \ tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id); #else -#define GET_TLS_DATA_FROM_THREAD(thread) \ +#define GET_TLS_DATA_FROM_THREAD(...) \ DebuggerTlsData *tls; \ tls = &debugger_wasm_thread; #define GET_DEBUGGER_TLS() \ @@ -1614,6 +1614,12 @@ mono_init_debugger_agent_for_wasm (int log_level_parm, MonoProfilerHandle *prof) mono_profiler_set_jit_done_callback (*prof, jit_done); } + +void +mono_change_log_level (int new_log_level) +{ + log_level = new_log_level; +} #endif @@ -3687,6 +3693,10 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx get_objref (keepalive_obj); } +#ifdef TARGET_WASM + PRINT_DEBUG_MSG (1, "[%p] Sent %d events %s(%d), suspend=%d.\n", (gpointer) (gsize) mono_native_thread_id_get (), nevents, event_to_string (event), ecount, suspend_policy); +#endif + send_success = send_packet (CMD_SET_EVENT, CMD_COMPOSITE, &buf); if (send_success) { @@ -9002,7 +9012,6 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf) buffer_add_long (buf, (guint64)thread->tid); break; case CMD_THREAD_SET_IP: { - DebuggerTlsData *tls; MonoMethod *method; MonoDomain *domain; MonoSeqPointInfo *seq_points; @@ -9020,9 +9029,7 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf) wait_for_suspend (); } - mono_loader_lock (); - tls = (DebuggerTlsData *)mono_g_hash_table_lookup (thread_to_tls, thread); - mono_loader_unlock (); + GET_TLS_DATA_FROM_THREAD (thread); g_assert (tls); compute_frame_info (thread, tls, FALSE); @@ -9138,7 +9145,9 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) int objid; ErrorCode err; MonoThread *thread_obj; +#ifndef TARGET_WASM MonoInternalThread *thread; +#endif int pos, i, len, frame_idx; StackFrame *frame; MonoDebugMethodJitInfo *jit; @@ -9152,11 +9161,16 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (err != ERR_NONE) return err; +#ifndef TARGET_WASM thread = THREAD_TO_INTERNAL (thread_obj); - +#endif id = decode_id (p, &p, end); +#ifndef TARGET_WASM GET_TLS_DATA_FROM_THREAD (thread); +#else + GET_TLS_DATA_FROM_THREAD (); +#endif g_assert (tls); for (i = 0; i < tls->frame_count; ++i) { diff --git a/src/mono/mono/component/debugger-agent.h b/src/mono/mono/component/debugger-agent.h index 8ff34438d54da2..ec77b0bfaba8a1 100644 --- a/src/mono/mono/component/debugger-agent.h +++ b/src/mono/mono/component/debugger-agent.h @@ -25,6 +25,9 @@ mono_wasm_get_tls (void); void mono_init_debugger_agent_for_wasm (int log_level, MonoProfilerHandle *prof); +void +mono_change_log_level (int new_log_level); + void mono_wasm_save_thread_context (void); diff --git a/src/mono/mono/component/hot_reload.c b/src/mono/mono/component/hot_reload.c index 155dcdf6f2c9ab..f10540254619c1 100644 --- a/src/mono/mono/component/hot_reload.c +++ b/src/mono/mono/component/hot_reload.c @@ -1692,9 +1692,6 @@ apply_enclog_pass2 (MonoImage *image_base, BaselineInfo *base_info, uint32_t gen #if defined(ALLOW_METHOD_ADD) || defined(ALLOW_FIELD_ADD) MonoClass *add_member_klass = NULL; #endif -#ifdef ALLOW_METHOD_ADD - uint32_t add_param_method_index = 0; -#endif gboolean assemblyref_updated = FALSE; for (int i = 0; i < rows ; ++i) { @@ -1731,7 +1728,6 @@ apply_enclog_pass2 (MonoImage *image_base, BaselineInfo *base_info, uint32_t gen case ENC_FUNC_ADD_PARAM: { g_assert (token_table == MONO_TABLE_METHOD); - add_param_method_index = token_index; break; } #endif diff --git a/src/mono/mono/component/mini-wasm-debugger.c b/src/mono/mono/component/mini-wasm-debugger.c index 33728e8ca06092..faf918d9f79c67 100644 --- a/src/mono/mono/component/mini-wasm-debugger.c +++ b/src/mono/mono/component/mini-wasm-debugger.c @@ -33,6 +33,7 @@ static int log_level = 1; G_BEGIN_DECLS EMSCRIPTEN_KEEPALIVE void mono_wasm_set_is_debugger_attached (gboolean is_attached); +EMSCRIPTEN_KEEPALIVE void mono_wasm_change_debugger_log_level (int new_log_level); EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command, guint8* data, unsigned int size); EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_send_dbg_command_with_parms (int id, MdbgProtCommandSet command_set, int command, guint8* data, unsigned int size, int valtype, char* newvalue); @@ -355,6 +356,12 @@ mono_wasm_set_is_debugger_attached (gboolean is_attached) } } +EMSCRIPTEN_KEEPALIVE void +mono_wasm_change_debugger_log_level (int new_log_level) +{ + mono_change_log_level (new_log_level); +} + extern void mono_wasm_add_dbg_command_received(mono_bool res_ok, int id, void* buffer, int buffer_len); EMSCRIPTEN_KEEPALIVE gboolean diff --git a/src/mono/mono/metadata/class-init.c b/src/mono/mono/metadata/class-init.c index 00ab30ffbd76f2..36fdd82960f83b 100644 --- a/src/mono/mono/metadata/class-init.c +++ b/src/mono/mono/metadata/class-init.c @@ -346,6 +346,10 @@ mono_class_setup_fields (MonoClass *klass) mono_class_set_type_load_failure (klass, "Missing field layout info for %s", field->name); break; } + if (m_type_is_byref (field->type) && (offset % MONO_ABI_ALIGNOF (gpointer) != 0)) { + mono_class_set_type_load_failure (klass, "Field '%s' has an invalid offset", field->name); + break; + } if (offset < -1) { /*-1 is used to encode special static fields */ mono_class_set_type_load_failure (klass, "Field '%s' has a negative offset %d", field->name, offset); break; diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 8bd911b7830aa8..ec5325bc2aa2d3 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -2065,8 +2065,16 @@ ves_icall_RuntimeFieldInfo_SetValueInternal (MonoReflectionFieldHandle field, Mo case MONO_TYPE_VALUETYPE: case MONO_TYPE_PTR: isref = FALSE; - if (!MONO_HANDLE_IS_NULL (value)) - v = (char*)mono_object_handle_pin_unbox (value, &value_gchandle); + if (!MONO_HANDLE_IS_NULL (value)) { + if (m_class_is_valuetype (mono_handle_class (value))) + v = (char*)mono_object_handle_pin_unbox (value, &value_gchandle); + else { + char* n = g_strdup_printf ("Object of type '%s' cannot be converted to type '%s'.", m_class_get_name (mono_handle_class (value)), m_class_get_name (mono_class_from_mono_type_internal (type))); + mono_error_set_argument (error, cf->name, n); + g_free (n); + return; + } + } break; case MONO_TYPE_STRING: case MONO_TYPE_OBJECT: diff --git a/src/mono/mono/metadata/seq-points-data.c b/src/mono/mono/metadata/seq-points-data.c index fa80737f1e2b34..47208dbf26f8ed 100644 --- a/src/mono/mono/metadata/seq-points-data.c +++ b/src/mono/mono/metadata/seq-points-data.c @@ -409,7 +409,10 @@ mono_seq_point_data_read (SeqPointData *data, char *path) fseek(f, 0, SEEK_SET); buffer_orig = buffer = (guint8 *)g_malloc (fsize + 1); - fread(buffer_orig, fsize, 1, f); + size_t items = fread(buffer_orig, fsize, 1, f); + if (items != 1) + return FALSE; + fclose(f); entry_count = decode_var_int (buffer, &buffer); diff --git a/src/mono/mono/metadata/sre-encode.c b/src/mono/mono/metadata/sre-encode.c index 4bcbbf7683c4be..1a5520a4852fe3 100644 --- a/src/mono/mono/metadata/sre-encode.c +++ b/src/mono/mono/metadata/sre-encode.c @@ -422,7 +422,7 @@ mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType * HANDLE_FUNCTION_ENTER (); MonoDynamicTable *table; - guint32 token, enclosing; + guint32 token; MonoClass *klass; /* if the type requires a typespec, we must try that first*/ @@ -446,11 +446,8 @@ mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType * goto leave; } - if (m_class_get_nested_in (klass)) { - enclosing = mono_dynimage_encode_typedef_or_ref_full (assembly, m_class_get_byval_arg (m_class_get_nested_in (klass)), FALSE); - /* get the typeref idx of the enclosing type */ - enclosing >>= MONO_TYPEDEFORREF_BITS; - } + if (m_class_get_nested_in (klass)) + mono_dynimage_encode_typedef_or_ref_full (assembly, m_class_get_byval_arg (m_class_get_nested_in (klass)), FALSE); table = &assembly->tables [MONO_TABLE_TYPEREF]; token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */ g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token)); diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 4bfbd295199778..d7e370676fe6cb 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -2668,7 +2668,7 @@ compute_llvm_code_range (MonoAotModule *amodule, guint8 **code_start, guint8 **c #ifdef HOST_WASM gsize min = 1 << 30, max = 0; - gsize prev = 0; + //gsize prev = 0; // FIXME: This depends on emscripten allocating ftnptr ids sequentially for (int i = 0; i < amodule->info.nmethods; ++i) { @@ -2682,7 +2682,7 @@ compute_llvm_code_range (MonoAotModule *amodule, guint8 **code_start, guint8 **c min = val; else if (val > max) max = val; - prev = val; + //prev = val; } } if (max) { @@ -5689,12 +5689,16 @@ get_new_unbox_arbitrary_trampoline_frome_page (gpointer addr) static gpointer get_numerous_trampoline (MonoAotTrampoline tramp_type, int n_got_slots, MonoAotModule **out_amodule, guint32 *got_offset, guint32 *out_tramp_size) { +#ifndef DISABLE_ASSERT_MESSAGES MonoImage *image; +#endif MonoAotModule *amodule = get_mscorlib_aot_module (); int index, tramp_size; +#ifndef DISABLE_ASSERT_MESSAGES /* Currently, we keep all trampolines in the mscorlib AOT image */ image = mono_defaults.corlib; +#endif *out_amodule = amodule; diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index a249b3d6d3678c..ba1fa81246ad2d 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -2067,9 +2067,12 @@ mono_main (int argc, char* argv[]) MonoDomain *domain; MonoImageOpenStatus open_status; const char* aname, *mname = NULL; - int i, count = 1; - guint32 opt, action = DO_EXEC, recompilation_times = 1; + int i; +#ifndef DISABLE_JIT + int count = 1; MonoGraphOptions mono_graph_options = (MonoGraphOptions)0; +#endif + guint32 opt, action = DO_EXEC, recompilation_times = 1; int mini_verbose_level = 0; char *trace_options = NULL; char *aot_options = NULL; @@ -2222,6 +2225,7 @@ mono_main (int argc, char* argv[]) } else if (strcmp (argv [i], "--mixed-mode") == 0) { mixed_mode = TRUE; #endif +#ifndef DISABLE_JIT } else if (strcmp (argv [i], "--ncompile") == 0) { if (i + 1 >= argc){ fprintf (stderr, "error: --ncompile requires an argument\n"); @@ -2229,6 +2233,7 @@ mono_main (int argc, char* argv[]) } count = atoi (argv [++i]); action = DO_BENCH; +#endif } else if (strcmp (argv [i], "--trace") == 0) { trace_options = (char*)""; } else if (strncmp (argv [i], "--trace=", 8) == 0) { @@ -2346,6 +2351,7 @@ mono_main (int argc, char* argv[]) mname = argv [++i]; action = DO_BENCH; +#ifndef DISABLE_JIT } else if (strncmp (argv [i], "--graph=", 8) == 0) { if (i + 1 >= argc){ fprintf (stderr, "error: --graph option requires a method name argument\n"); @@ -2364,6 +2370,7 @@ mono_main (int argc, char* argv[]) mname = argv [++i]; mono_graph_options = MONO_GRAPH_CFG; action = DO_DRAW; +#endif } else if (strcmp (argv [i], "--debug") == 0) { enable_debugging = TRUE; } else if (strncmp (argv [i], "--debug=", 8) == 0) { diff --git a/src/mono/mono/mini/image-writer.c b/src/mono/mono/mini/image-writer.c index 436d2b316635fc..1f367a8e35318a 100644 --- a/src/mono/mono/mini/image-writer.c +++ b/src/mono/mono/mini/image-writer.c @@ -77,7 +77,7 @@ #elif defined(TARGET_ASM_GAS) && defined(TARGET_WIN32) #define AS_INT16_DIRECTIVE ".word" #elif defined(TARGET_ASM_GAS) -#define AS_INT16_DIRECTIVE ".hword" +#define AS_INT16_DIRECTIVE ".short" #else #define AS_INT16_DIRECTIVE ".word" #endif diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c index f814096630b0bd..412c9af50d7513 100644 --- a/src/mono/mono/mini/mini-exceptions.c +++ b/src/mono/mono/mini/mini-exceptions.c @@ -849,7 +849,7 @@ mono_get_generic_info_from_stack_frame (MonoJitInfo *ji, MonoContext *ctx) } method = jinfo_get_method (ji); - if (mono_method_get_context (method)->method_inst) { + if (mono_method_get_context (method)->method_inst || mini_method_is_default_method (method)) { /* A MonoMethodRuntimeGenericContext* */ return info; } else if ((method->flags & METHOD_ATTRIBUTE_STATIC) || m_class_is_valuetype (method->klass)) { diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 91811f678deb66..6ba217275875fa 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -1739,7 +1739,9 @@ mini_get_interp_in_wrapper (MonoMethodSignature *sig) static GHashTable *cache; const char *name; gboolean generic = FALSE; +#ifndef DISABLE_JIT gboolean return_native_struct; +#endif sig = mini_get_underlying_reg_signature (sig); @@ -1763,7 +1765,9 @@ mini_get_interp_in_wrapper (MonoMethodSignature *sig) * stack, pass this address to the interp_entry and when we return it we use * CEE_MONO_LDNATIVEOBJ */ +#ifndef DISABLE_JIT return_native_struct = sig->ret->type == MONO_TYPE_VALUETYPE && sig->pinvoke && !sig->marshalling_disabled; +#endif /* Create the signature for the wrapper */ csig = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + (sig->param_count * sizeof (MonoType*))); diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index a52e6cb1a76288..93cc2a51357fce 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -3285,7 +3285,7 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void static MonoObject* mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error) { - MonoMethod *invoke, *callee; + MonoMethod *callee; MonoObject *(*runtime_invoke) (MonoObject *this_obj, void **params, MonoObject **exc, void* compiled_method); RuntimeInvokeInfo *info, *info2; MonoJitInfo *ji = NULL; @@ -3328,7 +3328,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec MonoMethod *wrapper; wrapper = mono_marshal_get_array_accessor_wrapper (method); - invoke = mono_marshal_get_runtime_invoke (wrapper, FALSE); + mono_marshal_get_runtime_invoke (wrapper, FALSE); callee = wrapper; } else { callee = NULL; @@ -3404,8 +3404,8 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec static RuntimeInvokeDynamicFunction dyn_runtime_invoke = NULL; if (info->dyn_call_info) { if (!dyn_runtime_invoke) { - invoke = mono_marshal_get_runtime_invoke_dynamic (); - RuntimeInvokeDynamicFunction invoke_func = (RuntimeInvokeDynamicFunction)mono_jit_compile_method_jit_only (invoke, error); + MonoMethod *dynamic_invoke = mono_marshal_get_runtime_invoke_dynamic (); + RuntimeInvokeDynamicFunction invoke_func = (RuntimeInvokeDynamicFunction)mono_jit_compile_method_jit_only (dynamic_invoke, error); mono_memory_barrier (); dyn_runtime_invoke = invoke_func; if (!dyn_runtime_invoke && mono_use_interpreter) { diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index f341690dd7d590..4d1af4eeb520a5 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -209,7 +209,6 @@ mono_arch_create_vars (MonoCompile *cfg) { MonoMethodSignature *sig; CallInfo *cinfo; - MonoType *sig_ret; sig = mono_method_signature_internal (cfg->method); @@ -220,7 +219,7 @@ mono_arch_create_vars (MonoCompile *cfg) // if (cinfo->ret.storage == ArgValuetypeInReg) // cfg->ret_var_is_local = TRUE; - sig_ret = mini_get_underlying_type (sig->ret); + mini_get_underlying_type (sig->ret); if (cinfo->ret.storage == ArgValuetypeAddrInIReg || cinfo->ret.storage == ArgGsharedVTOnStack) { cfg->vret_addr = mono_compile_create_var (cfg, mono_get_int_type (), OP_ARG); if (G_UNLIKELY (cfg->verbose_level > 1)) { @@ -647,8 +646,6 @@ mono_arch_patch_code_new (MonoCompile *cfg, guint8 *code, MonoJumpInfo *ji, gpoi G_BEGIN_DECLS -void * getgrnam (const char *name); -void * getgrgid (gid_t gid); int inotify_init (void); int inotify_rm_watch (int fd, int wd); int inotify_add_watch (int fd, const char *pathname, uint32_t mask); @@ -678,13 +675,6 @@ pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *pa return 0; } -int -pthread_sigmask (int how, const sigset_t *set, sigset_t *oset) -{ - return 0; -} - - int sigsuspend(const sigset_t *sigmask) { @@ -698,18 +688,6 @@ getdtablesize (void) return 256; //random constant that is the fd limit } -void * -getgrnam (const char *name) -{ - return NULL; -} - -void * -getgrgid (gid_t gid) -{ - return NULL; -} - int inotify_init (void) { @@ -747,22 +725,6 @@ ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) return -1; } -int -getpwnam_r (const char *name, struct passwd *pwd, char *buffer, size_t bufsize, - struct passwd **result) -{ - *result = NULL; - return ENOTSUP; -} - -int -getpwuid_r (uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, - struct passwd **result) -{ - *result = NULL; - return ENOTSUP; -} - G_END_DECLS /* Helper for runtime debugging */ diff --git a/src/mono/mono/sgen/sgen-gc.h b/src/mono/mono/sgen/sgen-gc.h index ef7569f4fe980d..43e397727abdd7 100644 --- a/src/mono/mono/sgen/sgen-gc.h +++ b/src/mono/mono/sgen/sgen-gc.h @@ -1222,6 +1222,7 @@ sgen_dummy_use (gpointer v) { #if defined(_MSC_VER) || defined(HOST_WASM) static volatile gpointer ptr; + (void)ptr; // avoid compiler warning: variable 'ptr' set but not used ptr = v; #elif defined(__GNUC__) __asm__ volatile ("" : "=r"(v) : "r"(v)); diff --git a/src/mono/mono/sgen/sgen-workers.h b/src/mono/mono/sgen/sgen-workers.h index 577466ea3c325d..cb42d695aee895 100644 --- a/src/mono/mono/sgen/sgen-workers.h +++ b/src/mono/mono/sgen/sgen-workers.h @@ -81,7 +81,7 @@ void sgen_workers_set_num_active_workers (int generation, int num_workers); #ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC void sgen_workers_start_all_workers (int generation, SgenObjectOperations *object_ops_nopar, SgenObjectOperations *object_ops_par, SgenWorkersFinishCallback finish_job); #else -#define sgen_workers_start_all_workers(...) +#define sgen_workers_start_all_workers(generation, object_ops_nopar, object_ops_par, finish_job) (void)object_ops_par; // avoid compiler warning: variable 'object_ops_par' set but not used #endif void sgen_workers_enqueue_job (int generation, SgenThreadPoolJob *job, gboolean enqueue); diff --git a/src/mono/mono/utils/mono-mmap-wasm.c b/src/mono/mono/utils/mono-mmap-wasm.c index 3364ec4fed939e..bf325fa8959ea2 100644 --- a/src/mono/mono/utils/mono-mmap-wasm.c +++ b/src/mono/mono/utils/mono-mmap-wasm.c @@ -161,7 +161,6 @@ int mono_vfree (void *addr, size_t length, MonoMemAccountType type) { VallocInfo *info = (VallocInfo*)(valloc_hash ? g_hash_table_lookup (valloc_hash, addr) : NULL); - int res; if (info) { /* @@ -169,13 +168,13 @@ mono_vfree (void *addr, size_t length, MonoMemAccountType type) * mono_valloc_align (), free the original mapping. */ BEGIN_CRITICAL_SECTION; - res = munmap (info->addr, info->size); + munmap (info->addr, info->size); END_CRITICAL_SECTION; g_free (info); g_hash_table_remove (valloc_hash, addr); } else { BEGIN_CRITICAL_SECTION; - res = munmap (addr, length); + munmap (addr, length); END_CRITICAL_SECTION; } diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.json.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.json.in index e34ff6d173b85a..b0fd53947e1351 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.json.in +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.json.in @@ -8,6 +8,7 @@ "description": ".NET WebAssembly build tools", "packs": [ "Microsoft.NET.Runtime.WebAssembly.Sdk", + "Microsoft.NET.Runtime.WebAssembly.Templates", "Microsoft.NETCore.App.Runtime.Mono.browser-wasm", "Microsoft.NETCore.App.Runtime.AOT.Cross.browser-wasm" ], @@ -140,6 +141,10 @@ "kind": "Sdk", "version": "${PackageVersion}" }, + "Microsoft.NET.Runtime.WebAssembly.Templates": { + "kind": "template", + "version": "${PackageVersion}" + }, "Microsoft.NETCore.App.Runtime.Mono.android-arm": { "kind": "framework", "version": "${PackageVersion}" diff --git a/src/mono/nuget/mono-packages.proj b/src/mono/nuget/mono-packages.proj index 75264e10296059..1c1c7c0bff9e3f 100644 --- a/src/mono/nuget/mono-packages.proj +++ b/src/mono/nuget/mono-packages.proj @@ -7,6 +7,7 @@ + diff --git a/src/mono/wasm/README.md b/src/mono/wasm/README.md index 37d5fa29643445..a016b9a1aa3001 100644 --- a/src/mono/wasm/README.md +++ b/src/mono/wasm/README.md @@ -161,7 +161,25 @@ To build and run the samples with AOT, add `/p:RunAOTCompilation=true` to the ab Also check [bench](../sample/wasm/browser-bench/README.md) sample to measure mono/wasm runtime performance. -### Upgrading Emscripten +## Templates + +The wasm templates, located in the `templates` directory, are templates for `dotnet new`, VS and VS for Mac. They are packaged and distributed as part of the `wasm-tools` workload. We have 2 templates, `wasmbrowser` and `wasmconsole`, for browser and console WebAssembly applications. + +For details about using `dotnet new` see the dotnet tool [documentation](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new). + +To test changes in the templates, use `dotnet new -i `. + +Example use of the `wasmconsole` template: + + > dotnet new wasmconsole + > dotnet publish + > cd bin/Debug/net7.0/browser-wasm/AppBundle + > node main.cjs + mono_wasm_runtime_ready fe00e07a-5519-4dfe-b35a-f867dbaf2e28 + Hello World! + Args: + +## Upgrading Emscripten Bumping Emscripten version involves these steps: diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 6fb3e5beda18a7..99180181d7a37e 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -151,6 +151,7 @@ <_MonoAotCrossCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','browser-wasm')) <_EmccDefaultFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-default.rsp')) + <_EmccDefaultLinkFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-link.rsp')) false true true @@ -216,10 +217,11 @@ <_EmccLDFlags Include="$(EmccLinkOptimizationFlag)" /> <_EmccLDFlags Include="@(_EmccCommonFlags)" /> - <_EmccLDFlags Include="-s TOTAL_MEMORY=$(EmccTotalMemory)" /> + <_EmccLDFlags Include="-Wl,--allow-undefined" /> + <_EmccLDSFlags Include="-s TOTAL_MEMORY=$(EmccTotalMemory)" /> - <_EmccLDFlags Include="-s ERROR_ON_UNDEFINED_SYMBOLS=0" Condition="'$(WasmBuildingForNestedPublish)' != 'true'" /> + <_EmccLDSFlags Include="-s ERROR_ON_UNDEFINED_SYMBOLS=0" Condition="'$(WasmBuildingForNestedPublish)' != 'true'" /> <_DriverCDependencies Include="$(_WasmPInvokeHPath);$(_WasmICallTablePath)" /> <_DriverCDependencies Include="$(_DriverGenCPath)" Condition="'$(_DriverGenCNeeded)' == 'true'" /> @@ -371,6 +373,7 @@ <_WasmExtraJSFile Include="@(Content)" Condition="'%(Content.Extension)' == '.js'" /> <_EmccLinkStepArgs Include="@(_EmccLDFlags)" /> + <_EmccLinkStepArgs Include="@(_EmccLDSFlags)" /> <_EmccLinkStepArgs Include="--%(_WasmExtraJSFile.Kind) "%(_WasmExtraJSFile.Identity)"" Condition="'%(_WasmExtraJSFile.Kind)' != ''" /> <_WasmLinkDependencies Include="@(_WasmExtraJSFile)" /> @@ -391,14 +394,14 @@ - + diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs index cf9eff051b886c..fbb25bff17e8e2 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -334,6 +334,7 @@ internal class MethodInfo public int IsAsync { get; set; } public DebuggerAttributesInfo DebuggerAttrInfo { get; set; } public TypeInfo TypeInfo { get; } + public bool HasSequencePoints { get => !DebugInformation.SequencePointsBlob.IsNil; } public MethodInfo(AssemblyInfo assembly, MethodDefinitionHandle methodDefHandle, int token, SourceFile source, TypeInfo type, MetadataReader asmMetadataReader, MetadataReader pdbMetadataReader) { @@ -348,7 +349,7 @@ public MethodInfo(AssemblyInfo assembly, MethodDefinitionHandle methodDefHandle, this.pdbMetadataReader = pdbMetadataReader; this.IsEnCMethod = false; this.TypeInfo = type; - if (!DebugInformation.SequencePointsBlob.IsNil) + if (HasSequencePoints) { var sps = DebugInformation.GetSequencePoints(); SequencePoint start = sps.First(); @@ -356,11 +357,15 @@ public MethodInfo(AssemblyInfo assembly, MethodDefinitionHandle methodDefHandle, foreach (SequencePoint sp in sps) { + if (sp.IsHidden) + continue; if (sp.StartLine < start.StartLine) start = sp; else if (sp.StartLine == start.StartLine && sp.StartColumn < start.StartColumn) start = sp; + if (end.EndLine == SequencePoint.HiddenLine) + end = sp; if (sp.EndLine > end.EndLine) end = sp; else if (sp.EndLine == end.EndLine && sp.EndColumn > end.EndColumn) @@ -406,7 +411,7 @@ public void UpdateEnC(MetadataReader asmMetadataReader, MetadataReader pdbMetada this.DebugInformation = pdbMetadataReaderParm.GetMethodDebugInformation(MetadataTokens.MethodDebugInformationHandle(method_idx)); this.pdbMetadataReader = pdbMetadataReaderParm; this.IsEnCMethod = true; - if (!DebugInformation.SequencePointsBlob.IsNil) + if (HasSequencePoints) { var sps = DebugInformation.GetSequencePoints(); SequencePoint start = sps.First(); @@ -434,7 +439,7 @@ public void UpdateEnC(MetadataReader asmMetadataReader, MetadataReader pdbMetada public SourceLocation GetLocationByIl(int pos) { SequencePoint? prev = null; - if (!DebugInformation.SequencePointsBlob.IsNil) { + if (HasSequencePoints) { foreach (SequencePoint sp in DebugInformation.GetSequencePoints()) { if (sp.Offset > pos) @@ -516,6 +521,12 @@ public bool ShouldStepOut(EventKind eventKind) return HasDebuggerHidden || (HasStepperBoundary && eventKind == EventKind.Step); } } + + public bool IsLexicallyContainedInMethod(MethodInfo containerMethod) + => (StartLocation.Line > containerMethod.StartLocation.Line || + (StartLocation.Line == containerMethod.StartLocation.Line && StartLocation.Column > containerMethod.StartLocation.Column)) && + (EndLocation.Line < containerMethod.EndLocation.Line || + (EndLocation.Line == containerMethod.EndLocation.Line && EndLocation.Column < containerMethod.EndLocation.Column)); } internal class TypeInfo @@ -1186,7 +1197,7 @@ private static bool Match(SequencePoint sp, SourceLocation start, SourceLocation if (end.Line < spStart.Line) return false; - if (end.Column < spStart.Column && end.Line == spStart.Line) + if (end.Column < spStart.Column && end.Line == spStart.Line && end.Column != -1) return false; return true; @@ -1213,17 +1224,19 @@ public List FindPossibleBreakpoints(SourceLocation start, Source } foreach (MethodInfo method in doc.Methods) + res.AddRange(FindBreakpointLocations(start, end, method)); + return res; + } + + public IEnumerable FindBreakpointLocations(SourceLocation start, SourceLocation end, MethodInfo method) + { + if (!method.HasSequencePoints) + yield break; + foreach (SequencePoint sequencePoint in method.DebugInformation.GetSequencePoints()) { - if (!method.DebugInformation.SequencePointsBlob.IsNil) - { - foreach (SequencePoint sequencePoint in method.DebugInformation.GetSequencePoints()) - { - if (!sequencePoint.IsHidden && Match(sequencePoint, start, end)) - res.Add(new SourceLocation(method, sequencePoint)); - } - } + if (!sequencePoint.IsHidden && Match(sequencePoint, start, end)) + yield return new SourceLocation(method, sequencePoint); } - return res; } /* diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs index 9b9c5a410cf2ff..0e028117bbf7e9 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs @@ -333,6 +333,8 @@ public ExecutionContext(MonoSDBHelper sdbAgent, int id, object auxData) private Dictionary perScopeCaches { get; } = new Dictionary(); + internal int TempBreakpointForSetNextIP { get; set; } + public DebugStore Store { get diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index aed459c2218c48..0bda696e16265f 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -499,6 +499,18 @@ protected override async Task AcceptCommand(MessageId id, string method, J } // Protocol extensions + case "DotnetDebugger.setNextIP": + { + var loc = SourceLocation.Parse(args?["location"] as JObject); + if (loc == null) + return false; + var ret = await OnSetNextIP(id, loc, token); + if (ret == true) + SendResponse(id, Result.OkFromObject(new { }), token); + else + SendResponse(id, Result.Err("Set next instruction pointer failed."), token); + return true; + } case "DotnetDebugger.applyUpdates": { if (await ApplyUpdates(id, args, token)) @@ -1046,6 +1058,11 @@ private async Task OnReceiveDebuggerAgentEvent(SessionId sessionId, JObjec case EventKind.Breakpoint: { Breakpoint bp = context.BreakpointRequests.Values.SelectMany(v => v.Locations).FirstOrDefault(b => b.RemoteId == request_id); + if (request_id == context.TempBreakpointForSetNextIP) + { + context.TempBreakpointForSetNextIP = -1; + await context.SdbAgent.RemoveBreakpoint(request_id, token); + } string reason = "other";//other means breakpoint int methodId = 0; if (event_kind != EventKind.UserBreak) @@ -1510,6 +1527,54 @@ private void OnCompileDotnetScript(MessageId msg_id, CancellationToken token) SendResponse(msg_id, Result.OkFromObject(new { }), token); } + private static bool IsNestedMethod(DebugStore store, Frame scope, SourceLocation foundLocation, SourceLocation targetLocation) + { + if (foundLocation.Line != targetLocation.Line || foundLocation.Column != targetLocation.Column) + { + SourceFile doc = store.GetFileById(scope.Method.Info.SourceId); + foreach (var method in doc.Methods) + { + if (method.Token == scope.Method.Info.Token) + continue; + if (method.IsLexicallyContainedInMethod(scope.Method.Info)) + continue; + SourceLocation newFoundLocation = store.FindBreakpointLocations(targetLocation, targetLocation, scope.Method.Info) + .FirstOrDefault(); + if (!(newFoundLocation is null)) + return true; + } + } + return false; + } + + private async Task OnSetNextIP(MessageId sessionId, SourceLocation targetLocation, CancellationToken token) + { + DebugStore store = await RuntimeReady(sessionId, token); + ExecutionContext context = GetContext(sessionId); + Frame scope = context.CallStack.First(); + + SourceLocation foundLocation = store.FindBreakpointLocations(targetLocation, targetLocation, scope.Method.Info) + .FirstOrDefault(); + + if (foundLocation is null) + return false; + + //search if it's a nested method and it's return false because we cannot move to another method + if (IsNestedMethod(store, scope, foundLocation, targetLocation)) + return false; + + var ilOffset = foundLocation.IlLocation; + var ret = await context.SdbAgent.SetNextIP(scope.Method, context.ThreadId, ilOffset, token); + + if (!ret) + return false; + + var breakpointId = await context.SdbAgent.SetBreakpoint(scope.Method.DebugId, ilOffset.Offset, token); + context.TempBreakpointForSetNextIP = breakpointId; + await SendCommand(sessionId, "Debugger.resume", new JObject(), token); + return true; + } + private async Task OnGetScriptSource(MessageId msg_id, string script_id, CancellationToken token) { if (!SourceId.TryParse(script_id, out SourceId id)) @@ -1524,7 +1589,7 @@ private async Task OnGetScriptSource(MessageId msg_id, string script_id, C using (Stream data = await src_file.GetSourceAsync(checkHash: false, token: token)) { - if (data.Length == 0) + if (data is MemoryStream && data.Length == 0) return false; using (var reader = new StreamReader(data)) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index 1d62e94f556f1b..173dfd3b26d8ff 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -2683,6 +2683,16 @@ public async Task SetVariableValue(int thread_id, int frame_id, int varId, return true; } + public async Task SetNextIP(MethodInfoWithDebugInformation method, int threadId, IlLocation ilOffset, CancellationToken token) + { + using var commandParamsWriter = new MonoBinaryWriter(); + commandParamsWriter.Write(threadId); + commandParamsWriter.Write(method.DebugId); + commandParamsWriter.Write((long)ilOffset.Offset); + using var getDebuggerCmdReader = await SendDebuggerAgentCommand(CmdThread.SetIp, commandParamsWriter, token); + return !getDebuggerCmdReader.HasError; + } + public async Task CreateByteArray(string diff, CancellationToken token) { var diffArr = Convert.FromBase64String(diff); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs index a9d17696c4faa9..438eceea378d3e 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs @@ -551,14 +551,12 @@ await CompareObjectPropertiesFor(frame_locals, "this", label: "this#0"); } -#if false // https://github.com/dotnet/runtime/issues/63560 [Fact] public async Task InvalidArrayId() => await CheckInspectLocalsAtBreakpointSite( "DebuggerTests.Container", "PlaceholderMethod", 1, "PlaceholderMethod", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ArrayTestsClass:ObjectArrayMembers'); }, 1);", wait_for_event_fn: async (pause_location) => { - int frame_idx = 1; var frame_locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); var c_obj = GetAndAssertObjectWithName(frame_locals, "c"); @@ -568,56 +566,12 @@ public async Task InvalidArrayId() => await CheckInspectLocalsAtBreakpointSite( // Invalid format await GetProperties("dotnet:array:4123", expect_ok: false); - // Invalid object id - await GetProperties("dotnet:array:{ \"arrayId\": 234980 }", expect_ok: false); - // Trying to access object as an array if (!DotnetObjectId.TryParse(c_obj_id, out var id) || id.Scheme != "object") Assert.True(false, "Unexpected object id format. Maybe this test is out of sync with the object id format in dotnet.cjs.lib.js?"); - if (!int.TryParse(id.Value, out var idNum)) - Assert.True(false, "Expected a numeric value part of the object id: {c_obj_id}"); - await GetProperties($"dotnet:array:{{\"arrayId\":{idNum}}}", expect_ok: false); - }); - - [Fact] - public async Task InvalidValueTypeArrayIndex() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.Container", "PlaceholderMethod", 1, "PlaceholderMethod", - "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ArrayTestsClass:ObjectArrayMembers'); }, 1);", - locals_fn: async (locals) => - { - var this_obj = GetAndAssertObjectWithName(locals, "this"); - var c_obj = GetAndAssertObjectWithName(await GetProperties(this_obj["value"]["objectId"].Value()), "c"); - var c_obj_id = c_obj["value"]?["objectId"]?.Value(); - Assert.NotNull(c_obj_id); - - var c_props = await GetProperties(c_obj_id); - - var pf_arr = GetAndAssertObjectWithName(c_props, "PointsField"); - var pf_arr_elems = await GetProperties(pf_arr["value"]["objectId"].Value()); - - if (!DotnetObjectId.TryParse(pf_arr_elems[0]["value"]?["objectId"]?.Value(), out var id)) - Assert.True(false, "Couldn't parse objectId for PointsFields' elements"); - - AssertEqual("valuetype", id.Scheme, "Expected a valuetype id"); - var id_args = id.ValueAsJson; - Assert.True(id_args["arrayId"] != null, "ObjectId format for array seems to have changed. Expected to find 'arrayId' in the value. Update this test"); - Assert.True(id_args != null, "Expected to get a json as the value part of {id}"); - - // Try one valid query, to confirm that the id format hasn't changed! - id_args["arrayIdx"] = 0; - await GetProperties($"dotnet:valuetype:{id_args.ToString(Newtonsoft.Json.Formatting.None)}", expect_ok: true); - - id_args["arrayIdx"] = 12399; - await GetProperties($"dotnet:valuetype:{id_args.ToString(Newtonsoft.Json.Formatting.None)}", expect_ok: false); - - id_args["arrayIdx"] = -1; - await GetProperties($"dotnet:valuetype:{id_args.ToString(Newtonsoft.Json.Formatting.None)}", expect_ok: false); - - id_args["arrayIdx"] = "qwe"; - await GetProperties($"dotnet:valuetype:{id_args.ToString(Newtonsoft.Json.Formatting.None)}", expect_ok: false); + await GetProperties($"dotnet:array:{id.Value}", expect_ok: false); }); -#endif [Fact] public async Task InvalidAccessors() => await CheckInspectLocalsAtBreakpointSite( diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs index 30c9417b6e484f..a56fdf6b988c9b 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs @@ -2,13 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Linq; using System.Threading.Tasks; using Microsoft.WebAssembly.Diagnostics; using Newtonsoft.Json.Linq; using System.IO; using Xunit; -using System.Threading; +using Xunit.Sdk; namespace DebuggerTests { @@ -294,11 +293,12 @@ await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test2.cs" } [Fact] - [Trait("Category", "windows-failing")] // https://github.com/dotnet/runtime/issues/62823 - [Trait("Category", "linux-failing")] // https://github.com/dotnet/runtime/issues/62823 public async Task BreakpointInAssemblyUsingTypeFromAnotherAssembly_BothDynamicallyLoaded() { int line = 7; + + // Start the task earlier than loading the assemblies, so we don't miss the event + Task bpResolved = WaitForBreakpointResolvedEvent(); await SetBreakpoint(".*/library-dependency-debugger-test1.cs$", line, 0, use_regex: true); await LoadAssemblyDynamically( Path.Combine(DebuggerTestAppPath, "library-dependency-debugger-test2.dll"), @@ -310,6 +310,8 @@ await LoadAssemblyDynamically( var source_location = "dotnet://library-dependency-debugger-test1.dll/library-dependency-debugger-test1.cs"; Assert.Contains(source_location, scripts.Values); + await bpResolved; + var pause_location = await EvaluateAndCheck( "window.setTimeout(function () { invoke_static_method('[library-dependency-debugger-test1] TestDependency:IntAdd', 5, 10); }, 1);", source_location, line, 8, @@ -1089,14 +1091,15 @@ public async Task CreateGoodBreakpointAndHitGoToWasmPageWithoutAssetsComeBackAnd expression = "window.setTimeout(function() { load_wasm_page_without_assets(); }, 1);" }); await cli.SendCommand("Runtime.evaluate", run_method, token); - await Task.Delay(1000, token); + await insp.WaitFor(Inspector.READY); + run_method = JObject.FromObject(new { expression = "window.setTimeout(function() { reload_wasm_page(); }, 1);" }); await cli.SendCommand("Runtime.evaluate", run_method, token); - await Task.Delay(1000, token); await insp.WaitFor(Inspector.READY); + await EvaluateAndCheck( "window.setTimeout(function() { invoke_add(); }, 1);", "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs index 23ac172cf69b17..26ea6e47e1ee31 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs @@ -475,6 +475,29 @@ internal async Task StepAndCheck(StepKind kind, string script_loc, int locals_fn: locals_fn); } + internal async Task SetNextIPAndCheck(string script_id, string script_loc, int line, int column, string function_name, + Func wait_for_event_fn = null, Func locals_fn = null, bool expected_error = false) + { + var setNextIPArgs = JObject.FromObject(new + { + scriptId = script_id, + lineNumber = line, + columnNumber = column + }); + + if (!expected_error) + { + return await SendCommandAndCheck( + JObject.FromObject(new { location = setNextIPArgs }), "DotnetDebugger.setNextIP", script_loc, line, column, function_name, + wait_for_event_fn: wait_for_event_fn, + locals_fn: locals_fn); + } + + var res = await cli.SendCommand("DotnetDebugger.setNextIP", JObject.FromObject(new { location = setNextIPArgs }), token); + Assert.False(res.IsOk); + return JObject.FromObject(res); + } + internal async Task EvaluateAndCheck( string expression, string script_loc, int line, int column, string function_name, Func wait_for_event_fn = null, Func locals_fn = null) @@ -1305,6 +1328,20 @@ internal async Task LoadAssemblyAndTestHotReload(string asm_file, strin return await insp.WaitFor(Inspector.PAUSE); } + public async Task WaitForBreakpointResolvedEvent() + { + try + { + var res = await insp.WaitForEvent("Debugger.breakpointResolved"); + Console.WriteLine ($"breakpoint resolved to {res}"); + return res; + } + catch (TaskCanceledException) + { + throw new XunitException($"Timed out waiting for Debugger.breakpointResolved event"); + } + } + internal async Task SetJustMyCode(bool enabled) { var req = JObject.FromObject(new { enabled = enabled }); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs index 46e3acc16dd941..9fbfa920f259b6 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ExceptionTests.cs @@ -235,7 +235,6 @@ await CheckValue(pause_location["data"], JObject.FromObject(new [Theory] [InlineData("[debugger-test] DebuggerTests.ExceptionTestsClassDefault:TestExceptions", "System.Exception", 76)] [InlineData("[debugger-test] DebuggerTests.ExceptionTestsClass:TestExceptions", "DebuggerTests.CustomException", 28)] - [Trait("Category", "linux-failing")] // https://github.com/dotnet/runtime/issues/62666 public async Task ExceptionTestAllWithReload(string entry_method_name, string class_name, int line_number) { var debugger_test_loc = "dotnet://debugger-test.dll/debugger-exception-test.cs"; @@ -249,14 +248,26 @@ public async Task ExceptionTestAllWithReload(string entry_method_name, string cl }), "Page.reload",null, 0, 0, null); Thread.Sleep(1000); - //send a lot of resumes to "skip" all the pauses on caught exception and completely reload the page - int i = 0; - while (i < 100) + // Hit resume to skip + int count = 0; + while(true) { - Result res = await cli.SendCommand("Debugger.resume", null, token); - i++; - } + await cli.SendCommand("Debugger.resume", null, token); + count++; + try + { + await insp.WaitFor(Inspector.PAUSE) + .WaitAsync(TimeSpan.FromSeconds(10)); + } + catch (TimeoutException) + { + // timed out waiting for a PAUSE + insp.ClearWaiterFor(Inspector.PAUSE); + break; + } + } + Console.WriteLine ($"* Resumed {count} times"); var eval_expr = "window.setTimeout(function() { invoke_static_method (" + $"'{entry_method_name}'" + @@ -309,7 +320,8 @@ async Task WaitForManagedException(JObject pause_location) AssertEqual("exception", pause_location["reason"]?.Value(), $"Expected to only pause because of an exception. {pause_location}"); // return in case of a managed exception, and ignore JS ones - if (pause_location["data"]?["objectId"]?.Value()?.StartsWith("dotnet:object:") == true) + if (pause_location["data"]?["objectId"]?.Value()?.StartsWith("dotnet:object:", StringComparison.Ordinal) == true || + pause_location["data"]?["uncaught"]?.Value() == true) { break; } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/HarnessTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/HarnessTests.cs index 865eaa8c630f5e..d164b9663887af 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/HarnessTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/HarnessTests.cs @@ -27,7 +27,7 @@ public async Task TimedOutWaitingForInvalidBreakpoint() public async Task ExceptionThrown() { var ae = await Assert.ThrowsAsync( - async () => await EvaluateAndCheck("window.setTimeout(function() { non_existant_fn(); }, 1);", null, -1, -1, null)); + async () => await EvaluateAndCheck("window.setTimeout(function() { non_existant_fn(); }, 3000);", null, -1, -1, null)); Assert.Contains("non_existant_fn is not defined", ae.Message); } @@ -35,15 +35,6 @@ public async Task ExceptionThrown() public async Task BrowserCrash() => await Assert.ThrowsAsync(async () => await SendCommandAndCheck(null, "Browser.crash", null, -1, -1, null)); - [Fact] - public async Task BrowserClose() - { - ArgumentException ae = await Assert.ThrowsAsync(async () => - await SendCommandAndCheck(null, "Browser.close", null, -1, -1, null)); - Assert.Contains("Inspector.detached", ae.Message); - Assert.Contains("target_close", ae.Message); - } - [Fact] public async Task InspectorWaitForAfterMessageAlreadyReceived() { diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs index c70f42f5d8449f..b44dddd02dbded 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs @@ -73,6 +73,12 @@ public Task WaitFor(string what) } } + public void ClearWaiterFor(string what) + { + if (notifications.ContainsKey(what)) + notifications.Remove(what); + } + void NotifyOf(string what, JObject args) { if (notifications.TryGetValue(what, out TaskCompletionSource? tcs)) @@ -96,6 +102,18 @@ public void On(string evtName, Func cb) eventListeners[evtName] = cb; } + public Task WaitForEvent(string evtName) + { + var eventReceived = new TaskCompletionSource(); + On(evtName, async (args, token) => + { + eventReceived.SetResult(args); + await Task.CompletedTask; + }); + + return eventReceived.Task.WaitAsync(Token); + } + void FailAllWaiters(Exception? exception = null) { // Because we can create already completed tasks, diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs index c19669bd0c88ec..6f705edcbcfb51 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/MiscTests.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Newtonsoft.Json.Linq; using Xunit; +using Xunit.Sdk; [assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] @@ -736,6 +737,7 @@ JObject FindFrame(JObject pause_location, string function_name) [Fact] public async Task DebugLazyLoadedAssemblyWithPdb() { + Task bpResolved = WaitForBreakpointResolvedEvent(); int line = 9; await SetBreakpoint(".*/lazy-debugger-test.cs$", line, 0, use_regex: true); await LoadAssemblyDynamically( @@ -744,7 +746,9 @@ await LoadAssemblyDynamically( var source_location = "dotnet://lazy-debugger-test.dll/lazy-debugger-test.cs"; Assert.Contains(source_location, scripts.Values); - System.Threading.Thread.Sleep(1000); + + await bpResolved; + var pause_location = await EvaluateAndCheck( "window.setTimeout(function () { invoke_static_method('[lazy-debugger-test] LazyMath:IntAdd', 5, 10); }, 1);", source_location, line, 8, @@ -755,9 +759,9 @@ await LoadAssemblyDynamically( } [Fact] - [Trait("Category", "linux-failing")] // https://github.com/dotnet/runtime/issues/62667 public async Task DebugLazyLoadedAssemblyWithEmbeddedPdb() { + Task bpResolved = WaitForBreakpointResolvedEvent(); int line = 9; await SetBreakpoint(".*/lazy-debugger-test-embedded.cs$", line, 0, use_regex: true); await LoadAssemblyDynamically( @@ -767,6 +771,8 @@ await LoadAssemblyDynamically( var source_location = "dotnet://lazy-debugger-test-embedded.dll/lazy-debugger-test-embedded.cs"; Assert.Contains(source_location, scripts.Values); + await bpResolved; + var pause_location = await EvaluateAndCheck( "window.setTimeout(function () { invoke_static_method('[lazy-debugger-test-embedded] LazyMath:IntAdd', 5, 10); }, 1);", source_location, line, 8, @@ -829,6 +835,26 @@ public async Task GetSourceUsingSourceLink() Assert.True(source.IsOk, $"Failed to getScriptSource: {source}"); } + [Fact] + public async Task GetSourceEmbeddedSource() + { + string asm_file = Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.dll"); + string pdb_file = Path.Combine(DebuggerTestAppPath, "ApplyUpdateReferencedAssembly.pdb"); + string asm_file_hot_reload = Path.Combine(DebuggerTestAppPath, "../wasm/ApplyUpdateReferencedAssembly.dll"); + + var bp = await SetBreakpoint(".*/MethodBody1.cs$", 48, 12, use_regex: true); + var pause_location = await LoadAssemblyAndTestHotReloadUsingSDBWithoutChanges( + asm_file, pdb_file, "MethodBody5", "StaticMethod1"); + + var sourceToGet = JObject.FromObject(new + { + scriptId = pause_location["callFrames"][0]["functionLocation"]["scriptId"].Value() + }); + + var source = await cli.SendCommand("Debugger.getScriptSource", sourceToGet, token); + Assert.False(source.Value["scriptSource"].Value().Contains("// Unable to read document")); + } + [Fact] public async Task InspectTaskAtLocals() => await CheckInspectLocalsAtBreakpointSite( "InspectTask", diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/SetNextIpTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/SetNextIpTests.cs new file mode 100644 index 00000000000000..3e6e117aad762f --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/SetNextIpTests.cs @@ -0,0 +1,280 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.WebAssembly.Diagnostics; +using Newtonsoft.Json.Linq; +using System.IO; +using Xunit; +using System.Threading; + +namespace DebuggerTests; + +public class SetNextIpTests : DebuggerTestBase +{ + [Fact] + public async Task SetAndCheck() + { + async Task CheckLocalsAsync(JToken locals, int c, int d, int e, bool f) + { + CheckNumber(locals, "c", c); + CheckNumber(locals, "d", d); + CheckNumber(locals, "e", e); + await CheckBool(locals, "f", f); + } + var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 9, 8); + + //calling invoke_add twice to check if the breakpoint continue working after calling SetNextIP + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_add(); invoke_add(); }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 9, 8, + "IntAdd" + ); + var top_frame = pause_location["callFrames"][0]["functionLocation"]; + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd", + locals_fn: async (locals) => await CheckLocalsAsync(locals, 0, 0, 0, false)); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 13, 8, "IntAdd", + locals_fn: async (locals) => await CheckLocalsAsync(locals, 0, 0, 0, true)); + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-test.cs", 9, 8, "IntAdd", + locals_fn: async (locals) => await CheckLocalsAsync(locals, 0, 0, 0, true)); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, "IntAdd", + locals_fn: async (locals) => await CheckLocalsAsync(locals, 30, 0, 0, true)); + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-test.cs", 11, 8, "IntAdd", + locals_fn: async (locals) => await CheckLocalsAsync(locals, 30, 0, 0, true)); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd", + locals_fn: async (locals) => await CheckLocalsAsync(locals, 30, 0, 10, true)); + + //to check that after moving the execution pointer to the same line that there is already + //a breakpoint, the breakpoint continue working + pause_location = await StepAndCheck(StepKind.Resume, + "dotnet://debugger-test.dll/debugger-test.cs", 9, 8, + "IntAdd"); + } + + [Fact] + public async Task OutsideTheCurrentMethod() + { + var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 9, 8); + + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_add(); }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 9, 8, + "IntAdd"); + var top_frame = pause_location["callFrames"][0]["functionLocation"]; + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-test.cs", 20, 8, "IntAdd", + expected_error: true); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, "IntAdd", + locals_fn: async (locals) => + { + CheckNumber(locals, "c", 30); + CheckNumber(locals, "d", 0); + CheckNumber(locals, "e", 0); + await CheckBool(locals, "f", false); + }); + } + + [Fact] + public async Task AsyncMethod() + { + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs"; + + await SetBreakpoint(debugger_test_loc, 140, 12); + + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_async_method_with_await(); }, 1);", + debugger_test_loc, 140, 12, "MoveNext", + locals_fn: async (locals) => + { + CheckNumber(locals, "li", 0); + CheckNumber(locals, "i", 42); + await CheckString(locals, "ls", null); + } + ); + var top_frame = pause_location["callFrames"][0]["functionLocation"]; + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-test.cs", 141, 12, "MoveNext", + locals_fn: async (locals) => + { + CheckNumber(locals, "li", 0); + CheckNumber(locals, "i", 42); + await CheckString(locals, "ls", null); + }); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 142, 12, "MoveNext", + locals_fn: async (locals) => + { + CheckNumber(locals, "li", 0); + CheckNumber(locals, "i", 42); + await CheckString(locals, "ls", "string from jstest"); + }); + } + + [Fact] + public async Task Lambda() + { + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-async-test.cs"; + + await SetBreakpoint(debugger_test_loc, 77, 12); + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests.AsyncTests.ContinueWithTests:RunAsync'); })", + debugger_test_loc, 77, 12, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }); + var top_frame = pause_location["callFrames"][0]["functionLocation"]; + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-async-test.cs", 79, 16, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-test.cs", 80, 16, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckDateTime(locals, "dt0", new DateTime(3412, 4, 6, 8, 0, 2)); + }); + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-async-test.cs", 91, 16, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckDateTime(locals, "dt0", new DateTime(3412, 4, 6, 8, 0, 2)); + }); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-test.cs", 92, 12, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckDateTime(locals, "dt0", new DateTime(3412, 4, 6, 8, 0, 2)); + }); + } + + [Fact] + public async Task Lambda_InvalidLocation() + { + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-async-test.cs"; + + await SetBreakpoint(debugger_test_loc, 77, 12); + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests.AsyncTests.ContinueWithTests:RunAsync'); })", + debugger_test_loc, 77, 12, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }); + var top_frame = pause_location["callFrames"][0]["functionLocation"]; + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-async-test.cs", 92, 8, "MoveNext", + expected_error: true); + + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-test.cs", 79, 16, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "RanToCompletion"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }, + times: 2); + } + + [Fact] + public async Task Lambda_ToNestedLambda() + { + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-async-test.cs"; + + await SetBreakpoint(debugger_test_loc, 77, 12); + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests.AsyncTests.ContinueWithTests:RunAsync'); })", + debugger_test_loc, 77, 12, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }); + var top_frame = pause_location["callFrames"][0]["functionLocation"]; + + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-async-test.cs", 88, 20, "MoveNext", + expected_error: true); + + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-test.cs", 79, 16, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "RanToCompletion"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }, + times: 2); + } + + [Fact] + public async Task Lambda_ToNestedSingleLineLambda_Invalid() + { + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-async-test.cs"; + + await SetBreakpoint(debugger_test_loc, 77, 12); + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests.AsyncTests.ContinueWithTests:RunAsync'); })", + debugger_test_loc, 77, 12, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }); + var top_frame = pause_location["callFrames"][0]["functionLocation"]; + + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-async-test.cs", 91, 58, "MoveNext", + expected_error: true); + + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-test.cs", 79, 16, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "RanToCompletion"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }, + times: 2); + } + + [Fact] + public async Task Lambda_ToNestedSingleLineLambda_Valid() + { + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-async-test.cs"; + + await SetBreakpoint(debugger_test_loc, 77, 12); + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests.AsyncTests.ContinueWithTests:RunAsync'); })", + debugger_test_loc, 77, 12, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }); + var top_frame = pause_location["callFrames"][0]["functionLocation"]; + + await SetNextIPAndCheck(top_frame["scriptId"].Value(), "dotnet://debugger-test.dll/debugger-async-test.cs", 91, 16, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }); + + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-test.cs", 92, 12, "MoveNext", + locals_fn: async (locals) => + { + await CheckString(locals, "str", "foobar"); + await CheckValueType(locals, "code", "System.Threading.Tasks.TaskStatus", description: "Created"); + await CheckValueType(locals, "dt0", "System.DateTime", description: "1/1/0001 12:00:00 AM"); + }); + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/ApplyUpdateReferencedAssembly.csproj b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/ApplyUpdateReferencedAssembly.csproj index 7ddd1b47740467..9b4c7a12d15077 100644 --- a/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/ApplyUpdateReferencedAssembly.csproj +++ b/src/mono/wasm/debugger/tests/ApplyUpdateReferencedAssembly/ApplyUpdateReferencedAssembly.csproj @@ -12,6 +12,7 @@ false false false + true true diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-async-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-async-test.cs index 56fafba63a8143..087e56201c2a4c 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-async-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-async-test.cs @@ -88,6 +88,8 @@ await Task.Delay(300).ContinueWith(t2 => var dt1 = new DateTime(4513, 4, 5, 6, 7, 8); Console.WriteLine ($"t2: {t2.Status}, str: {str}, {dt1}, {dt0}");//this, t2, dt1, str, dt0 }); + Console.WriteLine("done with this continueWith"); + await Task.Delay(300).ContinueWith(t2 => Console.WriteLine ($"t2: {t2.Status}, str: {str}, {dt0}")); }); Console.WriteLine ($"done with this method"); } diff --git a/src/mono/wasm/emscripten-version.txt b/src/mono/wasm/emscripten-version.txt index 8fe1046e01fc8e..59ef4a7aa83773 100644 --- a/src/mono/wasm/emscripten-version.txt +++ b/src/mono/wasm/emscripten-version.txt @@ -1 +1 @@ -2.0.23 \ No newline at end of file +2.0.34 \ No newline at end of file diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index 9721e39682c9ba..955228621ab938 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_EXECUTABLE_SUFFIX ".js") add_executable(dotnet corebindings.c driver.c pinvoke.c) target_include_directories(dotnet PUBLIC ${MONO_INCLUDES} ${MONO_OBJ_INCLUDES}) -target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/emcc-default.rsp -DCORE_BINDINGS -DGEN_PINVOKE=1) +target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-compile.rsp -DCORE_BINDINGS -DGEN_PINVOKE=1) set_target_properties(dotnet PROPERTIES COMPILE_FLAGS ${CONFIGURATION_EMCC_FLAGS}) @@ -25,7 +25,7 @@ target_link_libraries(dotnet set_target_properties(dotnet PROPERTIES LINK_DEPENDS "${NATIVE_BIN_DIR}/src/emcc-default.rsp;${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.pre.js;${NATIVE_BIN_DIR}/src/cjs/runtime.cjs.iffe.js;${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.lib.js;${NATIVE_BIN_DIR}/src/pal_random.lib.js;${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.post.js;${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.extpost.js;" - LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp ${CONFIGURATION_LINK_FLAGS} -DENABLE_NETCORE=1 --extern-pre-js ${NATIVE_BIN_DIR}/src/cjs/runtime.cjs.iffe.js --pre-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.pre.js --js-library ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.lib.js --js-library ${NATIVE_BIN_DIR}/src/pal_random.lib.js --post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.post.js --extern-post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.extpost.js " + LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-link.rsp ${CONFIGURATION_LINK_FLAGS} -DENABLE_NETCORE=1 --extern-pre-js ${NATIVE_BIN_DIR}/src/cjs/runtime.cjs.iffe.js --pre-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.pre.js --js-library ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.lib.js --js-library ${NATIVE_BIN_DIR}/src/pal_random.lib.js --post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.post.js --extern-post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.extpost.js " RUNTIME_OUTPUT_DIRECTORY "${NATIVE_BIN_DIR}") if(CMAKE_BUILD_TYPE STREQUAL "Release") diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index a2add7ec2fd680..93edd268995b0e 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -12,12 +12,13 @@ const DotnetSupportLib = { $DOTNET__postset: ` let __dotnet_replacements = {readAsync, fetch: globalThis.fetch, require}; let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports( - { isESM:false, isGlobal:ENVIRONMENT_IS_GLOBAL, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_, requirePromise:Promise.resolve(require)}, + { isESM:false, isGlobal:ENVIRONMENT_IS_GLOBAL, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_, ExitStatus, requirePromise:Promise.resolve(require)}, { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module }, __dotnet_replacements); readAsync = __dotnet_replacements.readAsync; var fetch = __dotnet_replacements.fetch; require = __dotnet_replacements.requireOut; +var noExitRuntime = __dotnet_replacements.noExitRuntime; `, }; diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index fab4a0e2645491..c3015f1ef3bc5d 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -28,6 +28,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_add_satellite_assembly", "void", ["string", "string", "number", "number"]], ["mono_wasm_load_runtime", null, ["string", "number"]], ["mono_wasm_exit", null, ["number"]], + ["mono_wasm_change_debugger_log_level", "void", ["number"]], // BINDING ["mono_wasm_get_corlib", "number", []], @@ -88,6 +89,7 @@ export interface t_Cwraps { mono_wasm_add_assembly(name: string, data: VoidPtr, size: number): number; mono_wasm_add_satellite_assembly(name: string, culture: string, data: VoidPtr, size: number): void; mono_wasm_load_runtime(unused: string, debug_level: number): void; + mono_wasm_change_debugger_log_level(value: number): void; // BINDING mono_wasm_get_corlib(): MonoAssembly; diff --git a/src/mono/wasm/runtime/debug.ts b/src/mono/wasm/runtime/debug.ts index 2aa8f121a55b80..ee10a5d9f5c97b 100644 --- a/src/mono/wasm/runtime/debug.ts +++ b/src/mono/wasm/runtime/debug.ts @@ -95,6 +95,10 @@ export function mono_wasm_detach_debugger(): void { cwraps.mono_wasm_set_is_debugger_attached(false); } +export function mono_wasm_change_debugger_log_level(level: number): void { + cwraps.mono_wasm_change_debugger_log_level(level); +} + /** * Raises an event for the debug proxy */ diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 36f5b106a1f4f5..98c6238cd3f0a7 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -49,12 +49,13 @@ if (ENVIRONMENT_IS_NODE) { } } let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports( - { isESM:true, isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_, requirePromise:__dotnet_replacements.requirePromise }, + { isESM:true, isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_, ExitStatus, requirePromise:__dotnet_replacements.requirePromise }, { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module }, __dotnet_replacements); readAsync = __dotnet_replacements.readAsync; var fetch = __dotnet_replacements.fetch; require = __dotnet_replacements.requireOut; +var noExitRuntime = __dotnet_replacements.noExitRuntime; `, }; diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 7942377aa411fe..5dc4d847db63c9 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -24,8 +24,9 @@ import { mono_wasm_debugger_log, mono_wasm_trace_logger, mono_wasm_add_dbg_command_received, + mono_wasm_change_debugger_log_level, } from "./debug"; -import { runtimeHelpers, setImportsAndExports } from "./imports"; +import { ENVIRONMENT_IS_WEB, ExitStatusError, runtimeHelpers, setImportsAndExports } from "./imports"; import { DotnetModuleConfigImports, DotnetModule } from "./types"; import { mono_load_runtime_and_bcl_args, mono_wasm_load_config, @@ -131,9 +132,9 @@ let exportedAPI: DotnetPublicAPI; // it exports methods to global objects MONO, BINDING and Module in backward compatible way // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types function initializeImportsAndExports( - imports: { isESM: boolean, isGlobal: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function, quit_: Function, requirePromise: Promise }, + imports: { isESM: boolean, isGlobal: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function, quit_: Function, ExitStatus: ExitStatusError, requirePromise: Promise }, exports: { mono: any, binding: any, internal: any, module: any }, - replacements: { fetch: any, readAsync: any, require: any, requireOut: any }, + replacements: { fetch: any, readAsync: any, require: any, requireOut: any, noExitRuntime: boolean }, ): DotnetPublicAPI { const module = exports.module as DotnetModule; const globalThisAny = globalThis as any; @@ -191,6 +192,8 @@ function initializeImportsAndExports( replacements.readAsync = readAsync_like; replacements.requireOut = module.imports.require; + replacements.noExitRuntime = ENVIRONMENT_IS_WEB; + if (typeof module.disableDotnet6Compatibility === "undefined") { module.disableDotnet6Compatibility = imports.isESM; } @@ -332,6 +335,7 @@ const INTERNAL: any = { mono_wasm_debugger_resume, mono_wasm_detach_debugger, mono_wasm_raise_debug_event, + mono_wasm_change_debugger_log_level, mono_wasm_runtime_is_ready: runtimeHelpers.mono_wasm_runtime_is_ready, }; diff --git a/src/mono/wasm/runtime/imports.ts b/src/mono/wasm/runtime/imports.ts index 47e4da482f4b57..808b579e1466c5 100644 --- a/src/mono/wasm/runtime/imports.ts +++ b/src/mono/wasm/runtime/imports.ts @@ -20,11 +20,16 @@ export let ENVIRONMENT_IS_SHELL: boolean; export let ENVIRONMENT_IS_WEB: boolean; export let locateFile: Function; export let quit: Function; +export let ExitStatus: ExitStatusError; export let requirePromise: Promise; +export interface ExitStatusError { + new(status: number): any; +} + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function setImportsAndExports( - imports: { isESM: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function, quit_: Function, requirePromise: Promise }, + imports: { isESM: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function, ExitStatus: ExitStatusError, quit_: Function, requirePromise: Promise }, exports: { mono: any, binding: any, internal: any, module: any }, ): void { MONO = exports.mono; @@ -37,6 +42,7 @@ export function setImportsAndExports( ENVIRONMENT_IS_WEB = imports.isWeb; locateFile = imports.locateFile; quit = imports.quit_; + ExitStatus = imports.ExitStatus; requirePromise = imports.requirePromise; } diff --git a/src/mono/wasm/runtime/run.ts b/src/mono/wasm/runtime/run.ts index 90185fbb00c6fa..f1e0000abeadfe 100644 --- a/src/mono/wasm/runtime/run.ts +++ b/src/mono/wasm/runtime/run.ts @@ -1,4 +1,4 @@ -import { Module, quit } from "./imports"; +import { ExitStatus, Module, quit } from "./imports"; import { mono_call_assembly_entry_point } from "./method-calls"; import { mono_wasm_set_main_args, runtime_is_initialized_reject } from "./startup"; @@ -8,6 +8,9 @@ export async function mono_run_main_and_exit(main_assembly_name: string, args: s const result = await mono_run_main(main_assembly_name, args); set_exit_code(result); } catch (error) { + if (error instanceof ExitStatus) { + return; + } set_exit_code(1, error); } } @@ -24,11 +27,14 @@ export function mono_on_abort(error: any): void { } function set_exit_code(exit_code: number, reason?: any) { - if (reason) { + if (reason && !(reason instanceof ExitStatus)) { Module.printErr(reason.toString()); if (reason.stack) { Module.printErr(reason.stack); } } + else { + reason = new ExitStatus(exit_code); + } quit(exit_code, reason); } diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index b208aeedcd06a8..cc0d1b24583e31 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -195,7 +195,7 @@ export function assert(condition: unknown, messsage: string): asserts condition } // see src/mono/wasm/driver.c MARSHAL_TYPE_xxx and Runtime.cs MarshalType -export enum MarshalType { +export const enum MarshalType { NULL = 0, INT = 1, FP64 = 2, @@ -230,7 +230,7 @@ export enum MarshalType { } // see src/mono/wasm/driver.c MARSHAL_ERROR_xxx and Runtime.cs -export enum MarshalError { +export const enum MarshalError { BUFFER_TOO_SMALL = 512, NULL_CLASS_POINTER = 513, NULL_TYPE_POINTER = 514, diff --git a/src/mono/wasm/templates/Microsoft.NET.Runtime.WebAssembly.Templates.csproj b/src/mono/wasm/templates/Microsoft.NET.Runtime.WebAssembly.Templates.csproj new file mode 100644 index 00000000000000..77f730d55b23db --- /dev/null +++ b/src/mono/wasm/templates/Microsoft.NET.Runtime.WebAssembly.Templates.csproj @@ -0,0 +1,33 @@ + + + + Template + Microsoft.NET.Runtime.WebAssembly.Templates + WebAssembly Templates + Microsoft + Templates to create WebAssembly projects. + dotnet-new;templates + + net6.0 + + true + false + content + $(NoWarn);NU5128 + true + + + + + + + + + + + + $(ProductVersion) + + + + diff --git a/src/mono/wasm/templates/templates/browser/.template.config/template.json b/src/mono/wasm/templates/templates/browser/.template.config/template.json new file mode 100644 index 00000000000000..e9736c68a1ba9c --- /dev/null +++ b/src/mono/wasm/templates/templates/browser/.template.config/template.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": [ "Web", "WebAssembly", "Browser" ], + "identity": "WebAssembly.Browser", + "name": "WebAssembly Browser App", + "shortName": "wasmbrowser", + "tags": { + "language": "C#", + "type": "project" + } +} diff --git a/src/mono/wasm/templates/templates/browser/Program.cs b/src/mono/wasm/templates/templates/browser/Program.cs new file mode 100644 index 00000000000000..baa90549b70363 --- /dev/null +++ b/src/mono/wasm/templates/templates/browser/Program.cs @@ -0,0 +1,12 @@ +using System; +using System.Runtime.CompilerServices; + +Console.WriteLine ("Hello, Console!"); + +public class MyClass { + [MethodImpl(MethodImplOptions.NoInlining)] + public static string CallMeFromJS() + { + return "Hello, World!"; + } +} diff --git a/src/mono/wasm/templates/templates/browser/browser.csproj b/src/mono/wasm/templates/templates/browser/browser.csproj new file mode 100644 index 00000000000000..6b36bc95f7f585 --- /dev/null +++ b/src/mono/wasm/templates/templates/browser/browser.csproj @@ -0,0 +1,17 @@ + + + net7.0 + wasm + Browser + browser-wasm + true + main.js + Exe + true + + + + + + + diff --git a/src/mono/wasm/templates/templates/browser/index.html b/src/mono/wasm/templates/templates/browser/index.html new file mode 100644 index 00000000000000..3cc12e3212d6b5 --- /dev/null +++ b/src/mono/wasm/templates/templates/browser/index.html @@ -0,0 +1,19 @@ + + + + + + + Sample ES6 + + + + + + + + + + + + diff --git a/src/mono/wasm/templates/templates/browser/main.js b/src/mono/wasm/templates/templates/browser/main.js new file mode 100644 index 00000000000000..56c9b350313ec1 --- /dev/null +++ b/src/mono/wasm/templates/templates/browser/main.js @@ -0,0 +1,13 @@ +import createDotnetRuntime from './dotnet.js' + +try { + const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime(); + const managedMethod = BINDING.bind_static_method("[browser] MyClass:CallMeFromJS"); + const text = managedMethod(); + document.getElementById("out").innerHTML = `${text}`; + + await MONO.mono_run_main("browser.dll", []); +} catch (err) { + console.log(`WASM ERROR ${err}`); + document.getElementById("out").innerHTML = `error: ${err}`; +} diff --git a/src/mono/wasm/templates/templates/console/.template.config/template.json b/src/mono/wasm/templates/templates/console/.template.config/template.json new file mode 100644 index 00000000000000..0a67c332bb7d7e --- /dev/null +++ b/src/mono/wasm/templates/templates/console/.template.config/template.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": [ "Web", "WebAssembly", "Console" ], + "identity": "WebAssembly.Console", + "name": "WebAssembly Console App", + "shortName": "wasmconsole", + "tags": { + "language": "C#", + "type": "project" + } +} diff --git a/src/mono/wasm/templates/templates/console/Program.cs b/src/mono/wasm/templates/templates/console/Program.cs new file mode 100644 index 00000000000000..3a242248ba2090 --- /dev/null +++ b/src/mono/wasm/templates/templates/console/Program.cs @@ -0,0 +1,9 @@ +using System; +using System.Threading.Tasks; + +Console.WriteLine("Hello World!"); + +Console.WriteLine("Args:"); +for (int i = 0; i < args.Length; i++) { + Console.WriteLine($" args[{i}] = {args[i]}"); +} diff --git a/src/mono/wasm/templates/templates/console/README.md b/src/mono/wasm/templates/templates/console/README.md new file mode 100644 index 00000000000000..0153a8574c1a94 --- /dev/null +++ b/src/mono/wasm/templates/templates/console/README.md @@ -0,0 +1,7 @@ +Node/CommonJS console App + +Run the published application like: + + node main.cjs + +in `bin/$(Configuration)/net7.0/browser-wasm/AppBundle` directory. diff --git a/src/mono/wasm/templates/templates/console/console.csproj b/src/mono/wasm/templates/templates/console/console.csproj new file mode 100644 index 00000000000000..fad622389dc305 --- /dev/null +++ b/src/mono/wasm/templates/templates/console/console.csproj @@ -0,0 +1,12 @@ + + + net7.0 + wasm + Browser + browser-wasm + true + main.cjs + Exe + false + + diff --git a/src/mono/wasm/templates/templates/console/main.cjs b/src/mono/wasm/templates/templates/console/main.cjs new file mode 100644 index 00000000000000..18823502c64fa7 --- /dev/null +++ b/src/mono/wasm/templates/templates/console/main.cjs @@ -0,0 +1,8 @@ +const createDotnetRuntime = require("./dotnet.js"); + +async function main() { + const { MONO } = await createDotnetRuntime(); + const app_args = process.argv.slice(2); + await MONO.mono_run_main_and_exit("console.dll", app_args); +}; +main(); diff --git a/src/mono/wasm/test-main.js b/src/mono/wasm/test-main.js index 9de96a2749fcc2..68a8bb3daee88a 100644 --- a/src/mono/wasm/test-main.js +++ b/src/mono/wasm/test-main.js @@ -127,7 +127,7 @@ loadDotnet("./dotnet.js").then((createDotnetRuntime) => { onConfigLoaded: (config) => { if (!Module.config) { const err = new Error("Could not find ./mono-config.json. Cancelling run"); - set_exit_code(1,); + set_exit_code(1); throw err; } // Have to set env vars here to enable setting MONO_LOG_LEVEL etc. @@ -214,7 +214,9 @@ const App = { const result = await MONO.mono_run_main(main_assembly_name, app_args); set_exit_code(result); } catch (error) { - set_exit_code(1, error); + if (error.name != "ExitStatus") { + set_exit_code(1, error); + } } } else { set_exit_code(1, "Unhandled argument: " + processedArguments.applicationArgs[0]); @@ -242,7 +244,7 @@ globalThis.App = App; // Necessary as System.Runtime.InteropServices.JavaScript. function set_exit_code(exit_code, reason) { if (reason) { - console.error(reason.toString()); + console.error(`${JSON.stringify(reason)}`); if (reason.stack) { console.error(reason.stack); } diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 7bbbf4073a2728..fffeeb55d7c2e3 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -12,6 +12,8 @@ emcc $(ArtifactsObjDir)wasm <_EmccDefaultsRspPath>$(NativeBinDir)src\emcc-default.rsp + <_EmccCompileRspPath>$(NativeBinDir)src\emcc-compile.rsp + <_EmccLinkRspPath>$(NativeBinDir)src\emcc-link.rsp false @@ -64,33 +66,41 @@ - <_EmccCommonFlags Include="-s ALLOW_MEMORY_GROWTH=1" /> - <_EmccCommonFlags Include="-s NO_EXIT_RUNTIME=1" /> - <_EmccCommonFlags Include="-s FORCE_FILESYSTEM=1" /> - <_EmccCommonFlags Include="-s EXPORTED_RUNTIME_METHODS="['FS','print','ccall','cwrap','setValue','getValue','UTF8ToString','UTF8ArrayToString','FS_createPath','FS_createDataFile','removeRunDependency','addRunDependency']"" /> - <_EmccCommonFlags Include="-s EXPORTED_FUNCTIONS="['_free','_malloc']"" /> - <_EmccCommonFlags Include="--source-map-base http://example.com" /> - - <_EmccCommonFlags Include="-s STRICT_JS=1" /> - <_EmccCommonFlags Include="-s EXPORT_NAME="'createDotnetRuntime'"" /> - <_EmccCommonFlags Include="-s MODULARIZE=1"/> - <_EmccCommonFlags Include="-s EXPORT_ES6=1" Condition="'$(WasmEnableES6)' == 'true'" /> + <_EmccLinkFlags Include="-s EXPORT_ES6=1" Condition="'$(WasmEnableES6)' == 'true'" /> + <_EmccLinkFlags Include="-s ALLOW_MEMORY_GROWTH=1" /> + <_EmccLinkFlags Include="-s NO_EXIT_RUNTIME=1" /> + <_EmccLinkFlags Include="-s FORCE_FILESYSTEM=1" /> + <_EmccLinkFlags Include="-s EXPORTED_RUNTIME_METHODS="['FS','print','ccall','cwrap','setValue','getValue','UTF8ToString','UTF8ArrayToString','FS_createPath','FS_createDataFile','removeRunDependency','addRunDependency']"" /> + <_EmccLinkFlags Include="-s EXPORTED_FUNCTIONS="['_free','_malloc']"" /> + <_EmccLinkFlags Include="--source-map-base http://example.com" /> + <_EmccLinkFlags Include="-s STRICT_JS=1" /> + <_EmccLinkFlags Include="-s EXPORT_NAME="'createDotnetRuntime'"" /> + <_EmccLinkFlags Include="-s MODULARIZE=1"/> + <_EmccLinkFlags Include="-Wl,--allow-undefined"/> + <_EmccLinkFlags Include="-s ENVIRONMENT="web,webview,worker,node,shell"" /> - <_EmccFlags Include="--profiling-funcs" /> + <_EmccLinkFlags Include="--profiling-funcs" /> <_EmccFlags Include="@(_EmccCommonFlags)" /> <_EmccFlags Include="@(_EmccCommonFlags)" /> - <_EmccFlags Include="-s USE_ZLIB=1" /> + + @@ -204,6 +214,8 @@ diff --git a/src/native/libs/System.IO.Compression.Native/CMakeLists.txt b/src/native/libs/System.IO.Compression.Native/CMakeLists.txt index 3070ede32e8fd0..83259d9ae29dbb 100644 --- a/src/native/libs/System.IO.Compression.Native/CMakeLists.txt +++ b/src/native/libs/System.IO.Compression.Native/CMakeLists.txt @@ -21,17 +21,19 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER) append_extra_compression_libs(NATIVE_LIBS_EXTRA) if (CLR_CMAKE_TARGET_BROWSER) - add_definitions(-s USE_ZLIB) - else () - # Disable implicit fallthrough warning for Brotli - set(FLAGS -Wno-implicit-fallthrough) + include(${CLR_SRC_NATIVE_DIR}/external/zlib.cmake) + add_definitions(-DINTERNAL_ZLIB) + set(NATIVECOMPRESSION_SOURCES ${ZLIB_SOURCES} ${NATIVECOMPRESSION_SOURCES}) + endif() - # Delete this supression once brotli is upgraded to vNext (current latest v1.0.9 - # does not contain upstream fix: https://github.com/google/brotli/commit/0a3944c) - set(FLAGS "${FLAGS} -Wno-vla-parameter") + # Disable implicit fallthrough warning for Brotli + set(FLAGS -Wno-implicit-fallthrough) - set_source_files_properties(${NATIVECOMPRESSION_SOURCES} PROPERTIES COMPILE_FLAGS ${FLAGS}) - endif () + # Delete this supression once brotli is upgraded to vNext (current latest v1.0.9 + # does not contain upstream fix: https://github.com/google/brotli/commit/0a3944c) + set(FLAGS "${FLAGS} -Wno-vla-parameter") + + set_source_files_properties(${NATIVECOMPRESSION_SOURCES} PROPERTIES COMPILE_FLAGS ${FLAGS}) if (GEN_SHARED_LIB) add_definitions(-DBROTLI_SHARED_COMPILATION) @@ -88,6 +90,7 @@ else () include(${CLR_SRC_NATIVE_DIR}/external/zlib.cmake) endif () + add_definitions(-DINTERNAL_ZLIB) set(NATIVECOMPRESSION_SOURCES ${ZLIB_SOURCES} ${NATIVECOMPRESSION_SOURCES}) if (GEN_SHARED_LIB) diff --git a/src/native/libs/System.IO.Compression.Native/pal_zlib.c b/src/native/libs/System.IO.Compression.Native/pal_zlib.c index b203e7d41921d0..f5d25d66106b02 100644 --- a/src/native/libs/System.IO.Compression.Native/pal_zlib.c +++ b/src/native/libs/System.IO.Compression.Native/pal_zlib.c @@ -5,8 +5,10 @@ #include #include "pal_zlib.h" -#ifdef _WIN32 - #define c_static_assert(e) static_assert((e),"") +#ifdef INTERNAL_ZLIB + #ifdef _WIN32 + #define c_static_assert(e) static_assert((e),"") + #endif #include #else #include "pal_utilities.h" diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index f6cf0d2aa23eac..4dd5c55dede84f 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -61,12 +61,33 @@ extern int getpeereid(int, uid_t *__restrict__, gid_t *__restrict__); #endif #endif -// The portable build is performed on RHEL7 which doesn't define FICLONE yet. -// Ensure FICLONE is defined for all Linux builds. #ifdef __linux__ +#include + +// Ensure FICLONE is defined for all Linux builds. #ifndef FICLONE #define FICLONE _IOW(0x94, 9, int) #endif + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-id-macro" +// Ensure __NR_copy_file_range is defined for portable builds. +#include // __NR_copy_file_range +# if !defined(__NR_copy_file_range) +# if defined(__amd64__) +# define __NR_copy_file_range 326 +# elif defined(__i386__) +# define __NR_copy_file_range 377 +# elif defined(__arm__) +# define __NR_copy_file_range 391 +# elif defined(__aarch64__) +# define __NR_copy_file_range 285 +# else +# error Unknown architecture +# endif +# endif +#pragma clang diagnostic pop + #endif #if HAVE_STAT64 @@ -1152,9 +1173,44 @@ static int32_t CopyFile_ReadWrite(int inFd, int outFd) } #endif // !HAVE_FCOPYFILE + +#ifdef __linux__ +static ssize_t CopyFileRange(int inFd, int outFd, size_t len) +{ + return syscall(__NR_copy_file_range, inFd, NULL, outFd, NULL, len, 0); +} + +static bool SupportsCopyFileRange() +{ + static volatile int s_isSupported = 0; + + int isSupported = s_isSupported; + if (isSupported == 0) + { + isSupported = -1; + + // Avoid known issues with copy_file_range that are fixed in Linux 5.3+ (https://lwn.net/Articles/789527/). + struct utsname name; + if (uname(&name) == 0) + { + unsigned int major = 0, minor = 0; + sscanf(name.release, "%u.%u", &major, &minor); + if (major > 5 || (major == 5 && minor >=3)) + { + isSupported = CopyFileRange(-1, -1, 0) == -1 && errno != ENOSYS ? 1 : -1; + } + } + + s_isSupported = isSupported; + } + return isSupported == 1; +} +#endif + int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd, int64_t sourceLength) { - (void)sourceLength; // unused on some platforms. + // unused on some platforms. + (void)sourceLength; int inFd = ToFileDescriptor(sourceFd); int outFd = ToFileDescriptor(destinationFd); @@ -1168,6 +1224,7 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd, int64_t // Get the stats on the source file. int ret; bool copied = false; + bool trySendFile = true; // Certain files (e.g. procfs) may return a size of 0 even though reading them will // produce data. We use plain read/write for those. @@ -1179,15 +1236,39 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd, int64_t copied = ret == 0; } #endif +#ifdef __linux__ + if (SupportsCopyFileRange() && !copied && sourceLength != 0) + { + do + { + size_t copyLength = (sourceLength >= SSIZE_MAX ? SSIZE_MAX : (size_t)sourceLength); + ssize_t sent = CopyFileRange(inFd, outFd, copyLength); + if (sent <= 0) + { + // sendfile will likely encounter the same error, don't try it. + trySendFile = false; + break; // Fall through. + } + else + { + assert(sent <= sourceLength); + sourceLength -= sent; + } + } while (sourceLength > 0); + + copied = sourceLength == 0; + } +#endif #if HAVE_SENDFILE_4 // Try copying the data using sendfile. - if (!copied && sourceLength != 0) + if (trySendFile && !copied && sourceLength != 0) { // Note that per man page for large files, you have to iterate until the // whole file is copied (Linux has a limit of 0x7ffff000 bytes copied). do { - ssize_t sent = sendfile(outFd, inFd, NULL, (sourceLength >= SSIZE_MAX ? SSIZE_MAX : (size_t)sourceLength)); + size_t copyLength = (sourceLength >= SSIZE_MAX ? SSIZE_MAX : (size_t)sourceLength); + ssize_t sent = sendfile(outFd, inFd, NULL, copyLength); if (sent < 0) { if (errno != EINVAL && errno != ENOSYS) diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c index 4dd95a119de599..0b52b0a100a8c9 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c @@ -316,7 +316,7 @@ int32_t AndroidCryptoNative_CipherCtxSetPadding(CipherCtx* ctx, int32_t padding) } } -int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx) +int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx, uint8_t* pIv, int32_t cIv) { if (!ctx) return FAIL; @@ -334,6 +334,20 @@ int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx) if (CheckJNIExceptions(env)) return FAIL; + if (pIv) + { + if (ctx->ivLength != cIv) + { + return FAIL; + } + + SaveTo(pIv, &ctx->iv, (size_t)ctx->ivLength, /* overwrite */ true); + } + else if (cIv != 0) + { + return FAIL; + } + return ReinitializeCipher(ctx); } diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h index 28d2fc52e8225a..6b9555967a5a73 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.h @@ -31,7 +31,7 @@ PALEXPORT int32_t AndroidCryptoNative_CipherSetTagLength(CipherCtx* ctx, int32_t PALEXPORT int32_t AndroidCryptoNative_CipherSetKeyAndIV(CipherCtx* ctx, uint8_t* key, uint8_t* iv, int32_t enc); PALEXPORT int32_t AndroidCryptoNative_CipherSetNonceLength(CipherCtx* ctx, int32_t ivLength); PALEXPORT void AndroidCryptoNative_CipherDestroy(CipherCtx* ctx); -PALEXPORT int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx); +PALEXPORT int32_t AndroidCryptoNative_CipherReset(CipherCtx* ctx, uint8_t* pIv, int32_t cIv); PALEXPORT int32_t AndroidCryptoNative_CipherCtxSetPadding(CipherCtx* ctx, int32_t padding); PALEXPORT int32_t AndroidCryptoNative_CipherUpdateAAD(CipherCtx* ctx, uint8_t* in, int32_t inl); PALEXPORT int32_t AndroidCryptoNative_CipherUpdate(CipherCtx* ctx, uint8_t* out, int32_t* outl, uint8_t* in, int32_t inl); diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index a64aac0c676e9c..bad52f66bde0c6 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -298,7 +298,6 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void); LEGACY_FUNCTION(EVP_CIPHER_CTX_cleanup) \ REQUIRED_FUNCTION(EVP_CIPHER_CTX_ctrl) \ FALLBACK_FUNCTION(EVP_CIPHER_CTX_free) \ - LIGHTUP_FUNCTION(EVP_CIPHER_CTX_get_original_iv) \ LEGACY_FUNCTION(EVP_CIPHER_CTX_init) \ FALLBACK_FUNCTION(EVP_CIPHER_CTX_new) \ FALLBACK_FUNCTION(EVP_CIPHER_CTX_reset) \ @@ -757,7 +756,6 @@ FOR_ALL_OPENSSL_FUNCTIONS #define EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_cleanup_ptr #define EVP_CIPHER_CTX_ctrl EVP_CIPHER_CTX_ctrl_ptr #define EVP_CIPHER_CTX_free EVP_CIPHER_CTX_free_ptr -#define EVP_CIPHER_CTX_get_original_iv EVP_CIPHER_CTX_get_original_iv_ptr #define EVP_CIPHER_CTX_init EVP_CIPHER_CTX_init_ptr #define EVP_CIPHER_CTX_new EVP_CIPHER_CTX_new_ptr #define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_reset_ptr diff --git a/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h b/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h index f7de24624eb98a..095dd3176e7aa4 100644 --- a/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h +++ b/src/native/libs/System.Security.Cryptography.Native/osslcompat_30.h @@ -18,7 +18,6 @@ typedef struct ossl_lib_ctx_st OSSL_LIB_CTX; void ERR_new(void); void ERR_set_debug(const char *file, int line, const char *func); void ERR_set_error(int lib, int reason, const char *fmt, ...); -int EVP_CIPHER_CTX_get_original_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len); int EVP_CIPHER_get_nid(const EVP_CIPHER *e); int EVP_MD_get_size(const EVP_MD* md); int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX* ctx, int bits); diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.c index 351a2cd1ca8cc7..ae2c0df5aae02c 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.c @@ -123,36 +123,12 @@ void CryptoNative_EvpCipherDestroy(EVP_CIPHER_CTX* ctx) } } -int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx) -{ - // EVP_CipherInit_ex with all nulls preserves the algorithm, resets the IV, - // and maintains the key. - // - // The only thing that you can't do is change the encryption direction, - // that requires passing the key and IV in again. - // - // But since we have a different object returned for CreateEncryptor - // and CreateDecryptor we don't need to worry about that. - uint8_t* iv = NULL; - -#ifdef NEED_OPENSSL_3_0 - // OpenSSL 3.0 alpha 13 does not properly reset the IV. Work around that by - // asking for the original IV, and giving it back. - uint8_t tmpIV[EVP_MAX_IV_LENGTH]; - - // If we're direct against 3.0, or we're portable and found 3.0 - if (API_EXISTS(EVP_CIPHER_CTX_get_original_iv)) - { - if (EVP_CIPHER_CTX_get_original_iv(ctx, tmpIV, sizeof(tmpIV)) != 1) - { - return 0; - } - - iv = tmpIV; - } -#endif +int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx, uint8_t* pIv, int32_t cIv) +{ + assert(cIv >= 0 && (pIv != NULL || cIv == 0)); + (void)cIv; - return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, KEEP_CURRENT_DIRECTION); + return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, pIv, KEEP_CURRENT_DIRECTION); } int32_t CryptoNative_EvpCipherCtxSetPadding(EVP_CIPHER_CTX* x, int32_t padding) diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.h b/src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.h index e9586fa93e9587..0899cea9dbe3af 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp_cipher.h @@ -35,7 +35,7 @@ EvpCipherReset Resets an EVP_CIPHER_CTX instance for a new computation. */ -PALEXPORT int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx); +PALEXPORT int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx, uint8_t* pIv, int32_t cIv); /* Function: diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c index b49ca41b1895d2..698e3282c45096 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c @@ -162,6 +162,19 @@ SSL_CTX* CryptoNative_SslCtxCreate(const SSL_METHOD* method) // to be to use server preference (as of June 2020), so just always assert that. SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION | SSL_OP_CIPHER_SERVER_PREFERENCE); +#ifdef NEED_OPENSSL_3_0 + if (CryptoNative_OpenSslVersionNumber() >= OPENSSL_VERSION_3_0_RTM) + { + // OpenSSL 3.0 forbids client-initiated renegotiation by default. To avoid platform + // differences, we explicitly enable it and handle AllowRenegotiation flag in managed + // code as in previous versions +#ifndef SSL_OP_ALLOW_CLIENT_RENEGOTIATION +#define SSL_OP_ALLOW_CLIENT_RENEGOTIATION ((uint64_t)1 << (uint64_t)8) +#endif + SSL_CTX_set_options(ctx, SSL_OP_ALLOW_CLIENT_RENEGOTIATION); + } +#endif + // If openssl.cnf doesn't have an opinion for CipherString, then use this value instead if (!g_config_specified_ciphersuites) { @@ -358,14 +371,34 @@ int32_t CryptoNative_SslSessionReused(SSL* ssl) return SSL_session_reused(ssl) == 1; } -int32_t CryptoNative_SslWrite(SSL* ssl, const void* buf, int32_t num) +int32_t CryptoNative_SslWrite(SSL* ssl, const void* buf, int32_t num, int32_t* error) { - return SSL_write(ssl, buf, num); + int32_t result = SSL_write(ssl, buf, num); + if (result > 0) + { + *error = SSL_ERROR_NONE; + } + else + { + *error = CryptoNative_SslGetError(ssl, result); + } + + return result; } -int32_t CryptoNative_SslRead(SSL* ssl, void* buf, int32_t num) +int32_t CryptoNative_SslRead(SSL* ssl, void* buf, int32_t num, int32_t* error) { - return SSL_read(ssl, buf, num); + int32_t result = SSL_read(ssl, buf, num); + if (result > 0) + { + *error = SSL_ERROR_NONE; + } + else + { + *error = CryptoNative_SslGetError(ssl, result); + } + + return result; } static int verify_callback(int preverify_ok, X509_STORE_CTX* store) @@ -376,7 +409,7 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX* store) return 1; } -int32_t CryptoNative_SslRenegotiate(SSL* ssl) +int32_t CryptoNative_SslRenegotiate(SSL* ssl, int32_t* error) { // The openssl context is destroyed so we can't use ticket or session resumption. SSL_set_options(ssl, SSL_OP_NO_TICKET | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); @@ -387,11 +420,15 @@ int32_t CryptoNative_SslRenegotiate(SSL* ssl) SSL_set_verify(ssl, SSL_VERIFY_PEER, verify_callback); int ret = SSL_renegotiate(ssl); if(ret != 1) + { + *error = CryptoNative_SslGetError(ssl, ret); return ret; + } - return SSL_do_handshake(ssl); + return CryptoNative_SslDoHandshake(ssl, error); } + *error = SSL_ERROR_NONE; return 0; } @@ -412,10 +449,20 @@ void CryptoNative_SslSetBio(SSL* ssl, BIO* rbio, BIO* wbio) SSL_set_bio(ssl, rbio, wbio); } -int32_t CryptoNative_SslDoHandshake(SSL* ssl) +int32_t CryptoNative_SslDoHandshake(SSL* ssl, int32_t* error) { ERR_clear_error(); - return SSL_do_handshake(ssl); + int32_t result = SSL_do_handshake(ssl); + if (result == 1) + { + *error = SSL_ERROR_NONE; + } + else + { + *error = CryptoNative_SslGetError(ssl, result); + } + + return result; } int32_t CryptoNative_IsSslStateOK(SSL* ssl) diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h index faf96988b1b507..bdbfed127af998 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h @@ -211,7 +211,7 @@ Shims the SSL_write method. Returns the positive number of bytes written when successful, 0 or a negative number when an error is encountered. */ -PALEXPORT int32_t CryptoNative_SslWrite(SSL* ssl, const void* buf, int32_t num); +PALEXPORT int32_t CryptoNative_SslWrite(SSL* ssl, const void* buf, int32_t num, int32_t* error); /* Shims the SSL_read method. @@ -219,14 +219,14 @@ Shims the SSL_read method. Returns the positive number of bytes read when successful, 0 or a negative number when an error is encountered. */ -PALEXPORT int32_t CryptoNative_SslRead(SSL* ssl, void* buf, int32_t num); +PALEXPORT int32_t CryptoNative_SslRead(SSL* ssl, void* buf, int32_t num, int32_t* error); /* Shims the SSL_renegotiate method. Returns 1 when renegotiation started; 0 on error. */ -PALEXPORT int32_t CryptoNative_SslRenegotiate(SSL* ssl); +PALEXPORT int32_t CryptoNative_SslRenegotiate(SSL* ssl, int32_t* error); /* Shims the SSL_renegotiate_pending method. @@ -259,7 +259,7 @@ Shims the SSL_do_handshake method. and by the specifications of the TLS/SSL protocol; <0 if the handshake was not successful because of a fatal error. */ -PALEXPORT int32_t CryptoNative_SslDoHandshake(SSL* ssl); +PALEXPORT int32_t CryptoNative_SslDoHandshake(SSL* ssl, int32_t* error); /* Gets a value indicating whether the SSL_state is SSL_ST_OK. diff --git a/src/tasks/AndroidAppBuilder/Templates/AndroidManifest.xml b/src/tasks/AndroidAppBuilder/Templates/AndroidManifest.xml index 12371dbd782af8..9d28b5efbdf3c8 100644 --- a/src/tasks/AndroidAppBuilder/Templates/AndroidManifest.xml +++ b/src/tasks/AndroidAppBuilder/Templates/AndroidManifest.xml @@ -9,7 +9,7 @@ - + diff --git a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java index a07a2ef8dc4a49..1f9654c0acf909 100644 --- a/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java +++ b/src/tasks/AndroidAppBuilder/Templates/MonoRunner.java @@ -35,6 +35,7 @@ public class MonoRunner extends Instrumentation System.loadLibrary("monodroid"); } + static String testResultsDir; static String entryPointLibName = "%EntryPointLibName%"; static Bundle result = new Bundle(); @@ -68,24 +69,24 @@ public void onCreate(Bundle arguments) { start(); } - private static String getDocsDir(Context ctx) { - File docsPath = ctx.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS); - if (docsPath == null) { - docsPath = ctx.getCacheDir(); - } - return docsPath.getAbsolutePath(); - } - public static int initialize(String entryPointLibName, String[] args, Context context) { String filesDir = context.getFilesDir().getAbsolutePath(); String cacheDir = context.getCacheDir().getAbsolutePath(); - String docsDir = getDocsDir(context); + + File docsPath = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS); + + // on Android API 30 there are "adb pull" permission issues with getExternalFilesDir() paths on emulators, see https://github.com/dotnet/xharness/issues/385 + if (docsPath == null || android.os.Build.VERSION.SDK_INT == 30) { + testResultsDir = context.getCacheDir().getAbsolutePath(); + } else { + testResultsDir = docsPath.getAbsolutePath(); + } // unzip libs and test files to filesDir unzipAssets(context, filesDir, "assets.zip"); Log.i("DOTNET", "MonoRunner initialize,, entryPointLibName=" + entryPointLibName); - return initRuntime(filesDir, cacheDir, docsDir, entryPointLibName, args); + return initRuntime(filesDir, cacheDir, testResultsDir, entryPointLibName, args); } @Override @@ -103,7 +104,7 @@ public void onStart() { result.putInt("return-code", retcode); // Xharness cli expects "test-results-path" with test results - File testResults = new File(getDocsDir(getContext()) + "/testResults.xml"); + File testResults = new File(testResultsDir + "/testResults.xml"); if (testResults.exists()) { Log.i("DOTNET", "MonoRunner finished, test-results-path=" + testResults.getAbsolutePath()); result.putString("test-results-path", testResults.getAbsolutePath()); @@ -146,7 +147,7 @@ static void unzipAssets(Context context, String toPath, String zipName) { } } - static native int initRuntime(String libsDir, String cacheDir, String docsDir, String entryPointLibName, String[] args); + static native int initRuntime(String libsDir, String cacheDir, String testResultsDir, String entryPointLibName, String[] args); static native int setEnv(String key, String value); } diff --git a/src/tasks/AndroidAppBuilder/Templates/monodroid.c b/src/tasks/AndroidAppBuilder/Templates/monodroid.c index 2e6f93f43a5d03..302324efd82df6 100644 --- a/src/tasks/AndroidAppBuilder/Templates/monodroid.c +++ b/src/tasks/AndroidAppBuilder/Templates/monodroid.c @@ -313,15 +313,15 @@ Java_net_dot_MonoRunner_setEnv (JNIEnv* env, jobject thiz, jstring j_key, jstrin } int -Java_net_dot_MonoRunner_initRuntime (JNIEnv* env, jobject thiz, jstring j_files_dir, jstring j_cache_dir, jstring j_docs_dir, jstring j_entryPointLibName, jobjectArray j_args) +Java_net_dot_MonoRunner_initRuntime (JNIEnv* env, jobject thiz, jstring j_files_dir, jstring j_cache_dir, jstring j_testresults_dir, jstring j_entryPointLibName, jobjectArray j_args) { char file_dir[2048]; char cache_dir[2048]; - char docs_dir[2048]; + char testresults_dir[2048]; char entryPointLibName[2048]; strncpy_str (env, file_dir, j_files_dir, sizeof(file_dir)); strncpy_str (env, cache_dir, j_cache_dir, sizeof(cache_dir)); - strncpy_str (env, docs_dir, j_docs_dir, sizeof(docs_dir)); + strncpy_str (env, testresults_dir, j_testresults_dir, sizeof(testresults_dir)); strncpy_str (env, entryPointLibName, j_entryPointLibName, sizeof(entryPointLibName)); bundle_path = file_dir; @@ -329,7 +329,7 @@ Java_net_dot_MonoRunner_initRuntime (JNIEnv* env, jobject thiz, jstring j_files_ setenv ("HOME", bundle_path, true); setenv ("TMPDIR", cache_dir, true); - setenv ("DOCSDIR", docs_dir, true); + setenv ("TEST_RESULTS_DIR", testresults_dir, true); int args_len = (*env)->GetArrayLength(env, j_args); int managed_argc = args_len + 1; diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs index ec37a933562bd7..4d3abaa401abec 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs @@ -127,7 +127,8 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs, string? buildDir = null, int expectedExitCode = 0, string? args = null, - Dictionary? envVars = null) + Dictionary? envVars = null, + string targetFramework = "net6.0") { buildDir ??= _projectDir; envVars ??= new(); @@ -144,7 +145,7 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs, envVars[kvp.Key] = kvp.Value; } - string bundleDir = Path.Combine(GetBinDir(baseDir: buildDir, config: buildArgs.Config), "AppBundle"); + string bundleDir = Path.Combine(GetBinDir(baseDir: buildDir, config: buildArgs.Config, targetFramework: targetFramework), "AppBundle"); (string testCommand, string extraXHarnessArgs) = host switch { RunHost.V8 => ("wasm test", "--js-file=test-main.js --engine=V8 -v trace"), @@ -341,8 +342,8 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp if (options.ExpectSuccess) { - string bundleDir = Path.Combine(GetBinDir(config: buildArgs.Config), "AppBundle"); - AssertBasicAppBundle(bundleDir, buildArgs.ProjectName, buildArgs.Config, options.HasIcudt, options.DotnetWasmFromRuntimePack ?? !buildArgs.AOT); + string bundleDir = Path.Combine(GetBinDir(config: buildArgs.Config, targetFramework: options.TargetFramework ?? "net6.0"), "AppBundle"); + AssertBasicAppBundle(bundleDir, buildArgs.ProjectName, buildArgs.Config, options.MainJS ?? "test-main.js", options.HasV8Script, options.HasIcudt, options.DotnetWasmFromRuntimePack ?? !buildArgs.AOT); } if (options.UseCache) @@ -371,6 +372,18 @@ public void InitBlazorWasmProjectDir(string id) File.Copy(Path.Combine(BuildEnvironment.TestDataPath, "Blazor.Directory.Build.targets"), Path.Combine(_projectDir, "Directory.Build.targets")); } + public string CreateWasmTemplateProject(string id, string template = "wasmbrowser") + { + InitPaths(id); + InitProjectDir(id); + new DotNetCommand(s_buildEnv, useDefaultArgs: false) + .WithWorkingDirectory(_projectDir!) + .ExecuteWithCapturedOutput($"new {template}") + .EnsureSuccessful(); + + return Path.Combine(_projectDir!, $"{id}.csproj"); + } + public string CreateBlazorWasmTemplateProject(string id) { InitBlazorWasmProjectDir(id); @@ -476,19 +489,19 @@ static void AssertRuntimePackPath(string buildOutput) throw new XunitException($"Runtime pack path doesn't match.{Environment.NewLine}Expected: {s_buildEnv.RuntimePackDir}{Environment.NewLine}Actual: {actualPath}"); } - protected static void AssertBasicAppBundle(string bundleDir, string projectName, string config, bool hasIcudt=true, bool dotnetWasmFromRuntimePack=true) + protected static void AssertBasicAppBundle(string bundleDir, string projectName, string config, string mainJS, bool hasV8Script, bool hasIcudt=true, bool dotnetWasmFromRuntimePack=true) { AssertFilesExist(bundleDir, new [] { "index.html", - "test-main.js", + mainJS, "dotnet.timezones.blat", "dotnet.wasm", "mono-config.json", - "dotnet.js", - "run-v8.sh" + "dotnet.js" }); + AssertFilesExist(bundleDir, new[] { "run-v8.sh" }, expectToExist: hasV8Script); AssertFilesExist(bundleDir, new[] { "icudt.dat" }, expectToExist: hasIcudt); string managedDir = Path.Combine(bundleDir, "managed"); @@ -866,7 +879,10 @@ public record BuildProjectOptions bool CreateProject = true, bool Publish = true, bool BuildOnlyAfterPublish = true, + bool HasV8Script = true, string? Verbosity = null, - string? Label = null + string? Label = null, + string? TargetFramework = null, + string? MainJS = null ); } diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs new file mode 100644 index 00000000000000..c23339c6d0c5e5 --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs @@ -0,0 +1,108 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; + +#nullable enable + +namespace Wasm.Build.Tests +{ + public class WasmTemplateTests : BuildTestBase + { + public WasmTemplateTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) + { + } + + [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [InlineData("Debug")] + [InlineData("Release")] + public void BrowserBuildThenPublish(string config) + { + string id = $"{config}_{Path.GetRandomFileName()}"; + string projectName = $"browser"; + CreateWasmTemplateProject(id, "wasmbrowser"); + + var buildArgs = new BuildArgs(projectName, config, false, id, null); + buildArgs = ExpandBuildArgs(buildArgs); + + BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + DotnetWasmFromRuntimePack: false, + CreateProject: false, + HasV8Script: false, + MainJS: "main.js", + Publish: false, + TargetFramework: "net7.0" + )); + + if (!_buildContext.TryGetBuildFor(buildArgs, out BuildProduct? product)) + throw new XunitException($"Test bug: could not get the build product in the cache"); + + File.Move(product!.LogFile, Path.ChangeExtension(product.LogFile!, ".first.binlog")); + + _testOutput.WriteLine($"{Environment.NewLine}Publishing with no changes ..{Environment.NewLine}"); + Console.WriteLine($"{Environment.NewLine}Publishing with no changes ..{Environment.NewLine}"); + + BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + DotnetWasmFromRuntimePack: false, + CreateProject: false, + HasV8Script: false, + MainJS: "main.js", + Publish: true, + TargetFramework: "net7.0", + UseCache: false)); + } + + [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [InlineData("Debug")] + [InlineData("Release")] + public void ConsoleBuildThenPublish(string config) + { + string id = $"{config}_{Path.GetRandomFileName()}"; + string projectName = $"console"; + CreateWasmTemplateProject(id, "wasmconsole"); + + var buildArgs = new BuildArgs(projectName, config, false, id, null); + buildArgs = ExpandBuildArgs(buildArgs); + + BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + DotnetWasmFromRuntimePack: true, + CreateProject: false, + HasV8Script: false, + MainJS: "main.cjs", + Publish: false, + TargetFramework: "net7.0" + )); + + if (!_buildContext.TryGetBuildFor(buildArgs, out BuildProduct? product)) + throw new XunitException($"Test bug: could not get the build product in the cache"); + + File.Move(product!.LogFile, Path.ChangeExtension(product.LogFile!, ".first.binlog")); + + _testOutput.WriteLine($"{Environment.NewLine}Publishing with no changes ..{Environment.NewLine}"); + Console.WriteLine($"{Environment.NewLine}Publishing with no changes ..{Environment.NewLine}"); + + bool expectRelinking = config == "Release"; + BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + DotnetWasmFromRuntimePack: !expectRelinking, + CreateProject: false, + HasV8Script: false, + MainJS: "main.cjs", + Publish: true, + TargetFramework: "net7.0", + UseCache: false)); + } + } +} diff --git a/src/tests/Common/CoreCLRTestLibrary/Utilities.cs b/src/tests/Common/CoreCLRTestLibrary/Utilities.cs index a7917eb640a84d..92f879051188af 100644 --- a/src/tests/Common/CoreCLRTestLibrary/Utilities.cs +++ b/src/tests/Common/CoreCLRTestLibrary/Utilities.cs @@ -91,6 +91,17 @@ public static bool IsWindowsIoTCore // return whether or not the OS is a 64 bit OS public static bool Is64 => (IntPtr.Size == 8); + public static bool IsMonoRuntime => Type.GetType("Mono.RuntimeStructs") != null; + public static bool IsNotMonoRuntime => !IsMonoRuntime; + public static bool IsNativeAot => IsNotMonoRuntime && !IsReflectionEmitSupported; +#if NETCOREAPP + public static bool IsReflectionEmitSupported => RuntimeFeature.IsDynamicCodeSupported; + public static bool IsNotReflectionEmitSupported => !IsReflectionEmitSupported; +#else + public static bool IsReflectionEmitSupported => true; +#endif + public static bool SupportsExceptionInterop => IsWindows && IsNotMonoRuntime && !IsNativeAot; // matches definitions in clr.featuredefines.props + public static string ByteArrayToString(byte[] bytes) { StringBuilder sb = new StringBuilder(); diff --git a/src/tests/Common/maui/MauiScenario.targets b/src/tests/Common/maui/MauiScenario.targets index 841b09e6141c7d..6928f98fce542b 100644 --- a/src/tests/Common/maui/MauiScenario.targets +++ b/src/tests/Common/maui/MauiScenario.targets @@ -3,7 +3,7 @@ - + @@ -18,6 +18,10 @@ Condition="'%(ResolvedRuntimePack.FrameworkName)' == 'Microsoft.NETCore.App' and '%(ResolvedRuntimePack.RuntimeIdentifier)' == 'android-x86'" /> + + - - - + + + + + + diff --git a/src/tests/Interop/DllImportAttribute/DllImportPath/DllImportPathTest.cs b/src/tests/Interop/DllImportAttribute/DllImportPath/DllImportPathTest.cs index c83295d89292a4..86d5098bf9fbda 100644 --- a/src/tests/Interop/DllImportAttribute/DllImportPath/DllImportPathTest.cs +++ b/src/tests/Interop/DllImportAttribute/DllImportPath/DllImportPathTest.cs @@ -52,7 +52,7 @@ class Test [DllImport(UnicodeFileName, EntryPoint = "GetZero")] private static extern int GetZero_Unicode(); - + [DllImport(PathEnvFileName, EntryPoint = "GetZero")] private static extern int GetZero_PathEnv(); @@ -83,7 +83,7 @@ static void TestNativeLibraryProbingOnRelativePath() bool isWindows = OperatingSystem.IsWindows(); if (!isWindows) // We need to ensure that the subdirectory exists for off-Windows. - { + { var currentDirectory = Directory.GetCurrentDirectory(); var info = new DirectoryInfo(currentDirectory); info.CreateSubdirectory(RelativeSubdirectoryName); @@ -97,12 +97,12 @@ static void TestNativeLibraryProbingOnRelativePath() { GetZero_Relative1Unix(); } - + if (OperatingSystem.IsWindows()) { GetZero_Relative2(); } - + if (isWindows) { GetZero_Relative3Windows(); @@ -150,7 +150,7 @@ private static void SetupUnicodeTest() localFile.Extension == ".dll" || localFile.Extension == ".so" || localFile.Extension == ".dylib"); - + var unicodeFileLocation = file.FullName.Replace("DllImportPath_Local", UnicodeFileName); file.CopyTo(unicodeFileLocation, true); @@ -178,7 +178,11 @@ public static int Main(string[] args) { TestNativeLibraryProbingUnicode(); } - TestNativeLibraryProbingOnPathEnv(); + // Setting LD_LIBRARY_PATH/DYLD_LIBRARY_PATH may not be allowed on Mac + if (!OperatingSystem.IsMacOS()) + { + TestNativeLibraryProbingOnPathEnv(); + } if (OperatingSystem.IsWindows()) { TestNativeExeProbing(); diff --git a/src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.cs b/src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.cs index 9c383b70214aad..cff2ff63b42981 100644 --- a/src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.cs +++ b/src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using Xunit; +using static TestLibrary.Utilities; namespace System.Runtime.InteropServices.Tests { @@ -167,11 +168,10 @@ public static void Parameter_CustomMarshalerProvided_CallsMethodsInCorrectOrderi // GetInstance is only called once. string val3 = "7488"; - Assert.Equal(val3, OrderTrackingMethodRef(ref val3)); + Assert.Equal(7488, OrderTrackingMethodRef(ref val3)); IEnumerable expectedOrderingThirdCall = expectedOrderingSecondCall.Concat(new string[] { "Called MarshalManagedToNative", - "Called MarshalNativeToManaged", "Called CleanUpManagedData", "Called MarshalNativeToManaged", "Called CleanUpNativeData", @@ -184,7 +184,7 @@ public static void Parameter_CustomMarshalerProvided_CallsMethodsInCorrectOrderi { "Called MarshalNativeToManaged", }); - Assert.Equal(expectedOrderingForthCall.Skip(12), OrderTrackingCustomMarshaler.Events.Skip(12)); + Assert.Equal(expectedOrderingForthCall.Skip(11), OrderTrackingCustomMarshaler.Events.Skip(11)); var val5 = OrderTrackingMethodDelegate(439, (x) => x.ToString()); Assert.Equal("439", val5); @@ -194,7 +194,15 @@ public static void Parameter_CustomMarshalerProvided_CallsMethodsInCorrectOrderi "Called CleanUpManagedData", "Called MarshalNativeToManaged", }); - Assert.Equal(expectedOrderingFifthCall.Skip(13), OrderTrackingCustomMarshaler.Events.Skip(13)); + Assert.Equal(expectedOrderingFifthCall.Skip(12), OrderTrackingCustomMarshaler.Events.Skip(12)); + + var val6 = OrderTrackingMethodReturn("726"); + Assert.Equal("726", val6); + IEnumerable expectedOrderingSixthCall = expectedOrderingFifthCall.Concat(new string[] + { + "Called MarshalNativeToManaged", + }); + Assert.Equal(expectedOrderingSixthCall.Skip(15), OrderTrackingCustomMarshaler.Events.Skip(15)); } // This should only be used *once*, as it uses static state. @@ -248,8 +256,7 @@ public static ICustomMarshaler GetInstance(string cookie) public static extern string OrderTrackingMethod([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] string str); [DllImport("CustomMarshalersPrimitives", EntryPoint = "NativeParseIntRef")] - [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] - public static extern string OrderTrackingMethodRef([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] ref string str); + public static extern int OrderTrackingMethodRef([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] ref string str); [DllImport("CustomMarshalersPrimitives", EntryPoint = "NativeParseIntOut")] public static extern void OrderTrackingMethodOut([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] out string str); @@ -261,6 +268,10 @@ public static ICustomMarshaler GetInstance(string cookie) [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] public static extern string OrderTrackingMethodDelegate(int val, TestDelegate dlg); + [DllImport("CustomMarshalersPrimitives", EntryPoint = "NativeParseInt")] + [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OrderTrackingCustomMarshaler))] + public static extern string OrderTrackingMethodReturn([MarshalAs(UnmanagedType.LPStr)] string str); + public static void CustomMarshaler_BothMarshalTypeRefAndMarshalTypeProvided_PicksMarshalType() { Assert.Equal(2, BothTypeRefAndTypeMethod("64001")); @@ -392,6 +403,14 @@ public static void Parameter_NullICustomMarshaler_ThrowsTypeLoadException() [DllImport(LibcLibrary, EntryPoint = "atoi", CallingConvention = CallingConvention.Cdecl)] public static extern int NullCustomMarshalerMethod([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = null)] string str); + public static void Parameter_InvalidTypeICustomMarshaler_TypeLoadException() + { + Assert.Throws(() => InvalidTypeCustomMarshalerMethod("")); + } + + [DllImport(LibcLibrary, EntryPoint = "atoi", CallingConvention = CallingConvention.Cdecl)] + public static extern int InvalidTypeCustomMarshalerMethod([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = "junk_type")] string str); + public static void Parameter_NotICustomMarshaler_ThrowsApplicationException() { Assert.Throws(() => NonICustomMarshalerMethod("")); @@ -658,11 +677,9 @@ public void CleanUpManagedData(object ManagedObj) { } [DllImport(LibcLibrary, EntryPoint = "atoi", CallingConvention = CallingConvention.Cdecl)] public static extern int DifferentCustomMarshalerType([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(OuterCustomMarshaler))] string str); - [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BoxedValueTypeCustomMarshaler))] public delegate string TestDelegateRef([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BoxedValueTypeCustomMarshaler))] ref int val); [DllImport("CustomMarshalersPrimitives", EntryPoint = "NativeParseIntDelegateRef")] - [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(BoxedValueTypeCustomMarshaler))] public static extern string CustomMarshallerWithDelegateRef(int val, TestDelegateRef dlg); public static void DelegateParameter_MarshalerOnRefInt_ThrowsMarshalDirectiveException() @@ -686,6 +703,7 @@ public static int Main(String[] args) Parameter_MarshalerOnValueType_ThrowsMarshalDirectiveException(); Parameter_MarshalerOnPointer_ThrowsMarshalDirectiveException(); Parameter_NullICustomMarshaler_ThrowsTypeLoadException(); + Parameter_InvalidTypeICustomMarshaler_TypeLoadException(); Parameter_NotICustomMarshaler_ThrowsApplicationException(); Parameter_OpenGenericICustomMarshaler_ThrowsTypeLoadException(); Parameter_GetInstanceMethodDoesntExist_ThrowsApplicationException(); @@ -699,7 +717,11 @@ public static int Main(String[] args) Parameter_CleanUpNativeDataMethodThrows_ThrowsActualException(); Field_ParentIsStruct_ThrowsTypeLoadException(); Parameter_DifferentCustomMarshalerType_MarshalsCorrectly(); - DelegateParameter_MarshalerOnRefInt_ThrowsMarshalDirectiveException(); + if (SupportsExceptionInterop) + { + // EH interop is not supported for NativeAOT. + DelegateParameter_MarshalerOnRefInt_ThrowsMarshalDirectiveException(); + } } catch (Exception e) { diff --git a/src/tests/JIT/Directed/debugging/debuginfo/tests.il b/src/tests/JIT/Directed/debugging/debuginfo/tests.il index 9f6dbfa8a5821c..7175b596692d2e 100644 --- a/src/tests/JIT/Directed/debugging/debuginfo/tests.il +++ b/src/tests/JIT/Directed/debugging/debuginfo/tests.il @@ -53,11 +53,13 @@ IL_000c: ret } + // fwdSub moves second call under the return tree + // .method public hidebysig static int32 TestLateFailingInlineCandidate() cil managed { .custom instance void [attribute]ExpectedILMappings::.ctor() = { property int32[] Debug = int32[2]( 0 6 ) - property int32[] Opts = int32[2]( 0 6 ) + property int32[] Opts = int32[2]( 0 0xE ) } .maxstack 2 .locals init (int32 V_0) diff --git a/src/tests/JIT/Methodical/Coverage/b518440.il b/src/tests/JIT/Methodical/Coverage/b518440.il index dfbe528c7a6dbe..afde124f1335c8 100644 --- a/src/tests/JIT/Methodical/Coverage/b518440.il +++ b/src/tests/JIT/Methodical/Coverage/b518440.il @@ -10,7 +10,6 @@ .assembly extern mscorlib{} .assembly b518440{} -.module b518440.exe .class public A { diff --git a/src/tests/JIT/Methodical/ELEMENT_TYPE_IU/ptr.il b/src/tests/JIT/Methodical/ELEMENT_TYPE_IU/ptr.il index 1d5a862dc42ca9..9cca4bf657e609 100644 --- a/src/tests/JIT/Methodical/ELEMENT_TYPE_IU/ptr.il +++ b/src/tests/JIT/Methodical/ELEMENT_TYPE_IU/ptr.il @@ -9,9 +9,8 @@ .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) .ver 4:0:0:0 } -.assembly 'test' +.assembly 'ptr' { } -.module 'test.exe' // MVID: {6048B3F7-DE21-4008-935A-6B43C5338841} .class value private explicit ansi sealed $MultiByte$size$120 { diff --git a/src/tests/JIT/Methodical/MDArray/GaussJordan/classarr.cs b/src/tests/JIT/Methodical/MDArray/GaussJordan/classarr.cs index d7e2f7b57fc14c..1ce5bc5e72f798 100644 --- a/src/tests/JIT/Methodical/MDArray/GaussJordan/classarr.cs +++ b/src/tests/JIT/Methodical/MDArray/GaussJordan/classarr.cs @@ -4,8 +4,9 @@ //Solving AX=B and the inverse of A with Gauss-Jordan algorithm using System; +using Xunit; -internal class MatrixCls +public class MatrixCls { public double[,] arr; public MatrixCls(int n, int m) @@ -14,7 +15,7 @@ public MatrixCls(int n, int m) } } -internal class classarr +public class classarr { private static double s_tolerance = 0.0000000000001; public static bool AreEqual(double left, double right) @@ -94,7 +95,8 @@ public static void gaussj(MatrixCls a, int n, MatrixCls b, int m) } } - public static int Main() + [Fact] + public static int TestEntryPoint() { bool pass = false; diff --git a/src/tests/JIT/Methodical/MDArray/GaussJordan/structarr.cs b/src/tests/JIT/Methodical/MDArray/GaussJordan/structarr.cs index 2515b3eb56d699..f9779d8015002e 100644 --- a/src/tests/JIT/Methodical/MDArray/GaussJordan/structarr.cs +++ b/src/tests/JIT/Methodical/MDArray/GaussJordan/structarr.cs @@ -4,8 +4,9 @@ //Solving AX=B and the inverse of A with Gauss-Jordan algorithm using System; +using Xunit; -internal struct MatrixStruct +public struct MatrixStruct { public double[,] arr; public MatrixStruct(int n, int m) @@ -14,7 +15,7 @@ public MatrixStruct(int n, int m) } } -internal class structarr +public class structarr { private static double s_tolerance = 0.0000000000001; public static bool AreEqual(double left, double right) @@ -93,7 +94,8 @@ public static void gaussj(MatrixStruct a, int n, MatrixStruct b, int m) } } - public static int Main() + [Fact] + public static int TestEntryPoint() { bool pass = false; diff --git a/src/tests/JIT/Methodical/VT/etc/ctor_recurse.cs b/src/tests/JIT/Methodical/VT/etc/ctor_recurse.cs index e3ef63fb354991..01fccd536b9dbc 100644 --- a/src/tests/JIT/Methodical/VT/etc/ctor_recurse.cs +++ b/src/tests/JIT/Methodical/VT/etc/ctor_recurse.cs @@ -2,16 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using Xunit; namespace Test { - internal class S + public class S { private T _nvalue; public S(T t) { _nvalue = t; } } - internal struct T + public struct T { private static T s_stat; private S _gcref; @@ -21,7 +22,8 @@ internal struct T private void DoMethod() { } - private static int Main() + [Fact] + public static int TestEntryPoint() { s_stat = new T(new S(new T(new S(new T(new S(new T(new S(new T(new S( diff --git a/src/tests/JIT/Methodical/VT/etc/han2.cs b/src/tests/JIT/Methodical/VT/etc/han2.cs index 453842187c7ceb..db1da0906a3539 100644 --- a/src/tests/JIT/Methodical/VT/etc/han2.cs +++ b/src/tests/JIT/Methodical/VT/etc/han2.cs @@ -2,15 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using Xunit; namespace JitTest { - internal struct Ring + public struct Ring { public int size; } - internal struct Column + public struct Column { public Ring[] rings; private int[] _heightPtr; @@ -65,7 +66,8 @@ private static int move(Column from, Column to, Column temp, int num) return C; } - private static int Main() + [Fact] + public static int TestEntryPoint() { int NUM = 17; Column[] cols = new Column[3]; diff --git a/src/tests/JIT/Methodical/VT/etc/han3.cs b/src/tests/JIT/Methodical/VT/etc/han3.cs index 8eef08c7872779..bb17a40d3ef04a 100644 --- a/src/tests/JIT/Methodical/VT/etc/han3.cs +++ b/src/tests/JIT/Methodical/VT/etc/han3.cs @@ -2,15 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using Xunit; namespace JitTest { - internal struct Ring + public struct Ring { public int size; } - internal struct Column + public struct Column { public Ring[] rings; private int[] _heightPtr; @@ -65,7 +66,8 @@ private static int move(Column from, Column to, Column temp, int num) return C; } - private static int Main() + [Fact] + public static int TestEntryPoint() { int NUM = 17; Column c1 = new Column(); diff --git a/src/tests/JIT/Methodical/VT/etc/han3_ctor.cs b/src/tests/JIT/Methodical/VT/etc/han3_ctor.cs index 5addcc161deaac..8a4137bc73fdb5 100644 --- a/src/tests/JIT/Methodical/VT/etc/han3_ctor.cs +++ b/src/tests/JIT/Methodical/VT/etc/han3_ctor.cs @@ -2,15 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using Xunit; namespace JitTest { - internal struct Ring + public struct Ring { public int size; } - internal struct Column + public struct Column { public Ring[] rings; private int[] _heightPtr; @@ -68,7 +69,8 @@ private static int move(Column from, Column to, Column temp, int num) return C; } - private static int Main() + [Fact] + public static int TestEntryPoint() { return move(new Column(17, 17), new Column(17, 0), diff --git a/src/tests/JIT/Methodical/VT/etc/han3_ref.cs b/src/tests/JIT/Methodical/VT/etc/han3_ref.cs index f4e097e2e5a437..02aa54f4048de5 100644 --- a/src/tests/JIT/Methodical/VT/etc/han3_ref.cs +++ b/src/tests/JIT/Methodical/VT/etc/han3_ref.cs @@ -2,15 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using Xunit; namespace JitTest { - internal struct Ring + public struct Ring { public int size; } - internal struct Column + public struct Column { public Ring[] rings; private int[] _heightPtr; @@ -68,7 +69,8 @@ private static int move(ref Column from, ref Column to, ref Column temp, int num return C; } - private static int Main() + [Fact] + public static int TestEntryPoint() { Column c1 = new Column(17, 17); Column c2 = new Column(17, 0); diff --git a/src/tests/JIT/Methodical/cctor/misc/assemname.cs b/src/tests/JIT/Methodical/cctor/misc/assemname.cs index f83108c2c2ec52..0bd4d577514d8f 100644 --- a/src/tests/JIT/Methodical/cctor/misc/assemname.cs +++ b/src/tests/JIT/Methodical/cctor/misc/assemname.cs @@ -7,7 +7,7 @@ namespace Precise { - internal class Driver + internal class Driver_assemname { public static int Main() { diff --git a/src/tests/JIT/Methodical/cctor/misc/deadlock.il b/src/tests/JIT/Methodical/cctor/misc/deadlock.il index d3b6e4bc2468f0..0c52d0b8590a11 100644 --- a/src/tests/JIT/Methodical/cctor/misc/deadlock.il +++ b/src/tests/JIT/Methodical/cctor/misc/deadlock.il @@ -9,30 +9,31 @@ } .assembly deadlock {} .assembly extern xunit.core {} +.namespace Test_deadlock { .class public A extends [mscorlib]System.Object { -.field static public class A a -.field static public class B b +.field static public class Test_deadlock.A a +.field static public class Test_deadlock.B b .method public static rtspecialname specialname void .cctor () { ldnull -stsfld class B A::b -ldsfld class A B::a -stsfld class A A::a +stsfld class Test_deadlock.B Test_deadlock.A::b +ldsfld class Test_deadlock.A Test_deadlock.B::a +stsfld class Test_deadlock.A Test_deadlock.A::a ret } } .class public B extends [mscorlib]System.Object { -.field static public class A a -.field static public class B b +.field static public class Test_deadlock.A a +.field static public class Test_deadlock.B b .method public static rtspecialname specialname void .cctor () { ldnull -stsfld class A B::a -ldsfld class B A::b -stsfld class B B::b +stsfld class Test_deadlock.A Test_deadlock.B::a +ldsfld class Test_deadlock.B Test_deadlock.A::b +stsfld class Test_deadlock.B Test_deadlock.B::b ret } } @@ -43,8 +44,9 @@ ret 01 00 00 00 ) .entrypoint -ldsfld class B A::b +ldsfld class Test_deadlock.B Test_deadlock.A::b pop ldc.i4 100 ret } +} diff --git a/src/tests/JIT/Methodical/cctor/misc/threads1.cs b/src/tests/JIT/Methodical/cctor/misc/threads1.cs index fc63ecfa6f9539..1f026536a73200 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads1.cs +++ b/src/tests/JIT/Methodical/cctor/misc/threads1.cs @@ -8,7 +8,7 @@ namespace Precise { - internal class Driver + internal class Driver_threads1 { public static void f() { diff --git a/src/tests/JIT/Methodical/cctor/misc/threads2.cs b/src/tests/JIT/Methodical/cctor/misc/threads2.cs index 49ecf79bd8097b..ef08f2d708119c 100644 --- a/src/tests/JIT/Methodical/cctor/misc/threads2.cs +++ b/src/tests/JIT/Methodical/cctor/misc/threads2.cs @@ -9,7 +9,7 @@ namespace Precise { - internal class Driver + internal class Driver_threads2 { public static void f() { diff --git a/src/tests/JIT/Methodical/cctor/xassem/xprecise1.cs b/src/tests/JIT/Methodical/cctor/xassem/xprecise1.cs index 0e3939247f45df..4ce195164d317c 100644 --- a/src/tests/JIT/Methodical/cctor/xassem/xprecise1.cs +++ b/src/tests/JIT/Methodical/cctor/xassem/xprecise1.cs @@ -3,7 +3,7 @@ // static method using System; namespace Precise { -class Driver +class Driver_xprecise1 { public static int Main() { diff --git a/src/tests/JIT/Methodical/cctor/xassem/xprecise1b.cs b/src/tests/JIT/Methodical/cctor/xassem/xprecise1b.cs index c230cd25cb1d57..b684fcf87135b4 100644 --- a/src/tests/JIT/Methodical/cctor/xassem/xprecise1b.cs +++ b/src/tests/JIT/Methodical/cctor/xassem/xprecise1b.cs @@ -5,7 +5,7 @@ using System; namespace Precise { - class Driver + class Driver_xprecise1b { public static int Main() { diff --git a/src/tests/JIT/Methodical/cctor/xassem/xprecise2.cs b/src/tests/JIT/Methodical/cctor/xassem/xprecise2.cs index 1fcf976357550b..9d3f13ad0e020b 100644 --- a/src/tests/JIT/Methodical/cctor/xassem/xprecise2.cs +++ b/src/tests/JIT/Methodical/cctor/xassem/xprecise2.cs @@ -5,7 +5,7 @@ using System; namespace Precise { - class Driver + class Driver_xprecise2 { public static int Main() { diff --git a/src/tests/JIT/Methodical/cctor/xassem/xprecise4.cs b/src/tests/JIT/Methodical/cctor/xassem/xprecise4.cs index e432c7b20b0856..70d08bd2dfd0ab 100644 --- a/src/tests/JIT/Methodical/cctor/xassem/xprecise4.cs +++ b/src/tests/JIT/Methodical/cctor/xassem/xprecise4.cs @@ -5,7 +5,7 @@ using System; namespace Precise { - class Driver + class Driver_xprecise4 { public static int Main() { diff --git a/src/tests/JIT/Methodical/eh/basics/emptyfinally.il b/src/tests/JIT/Methodical/eh/basics/emptyfinally.il index 0ad150dd5b1981..4e2f8081fa6b0f 100644 --- a/src/tests/JIT/Methodical/eh/basics/emptyfinally.il +++ b/src/tests/JIT/Methodical/eh/basics/emptyfinally.il @@ -48,7 +48,7 @@ .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/basics/throwinexcept.il b/src/tests/JIT/Methodical/eh/basics/throwinexcept.il index f75b47664650b2..d8eedf62122df2 100644 --- a/src/tests/JIT/Methodical/eh/basics/throwinexcept.il +++ b/src/tests/JIT/Methodical/eh/basics/throwinexcept.il @@ -10,9 +10,9 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'throwinexcept' {} +.class public auto ansi Test_throwinexcept extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -85,3 +85,4 @@ done2: ret } +} diff --git a/src/tests/JIT/Methodical/eh/basics/throwinfault.il b/src/tests/JIT/Methodical/eh/basics/throwinfault.il index e4adb4eda7e381..b5a1a3134f03f2 100644 --- a/src/tests/JIT/Methodical/eh/basics/throwinfault.il +++ b/src/tests/JIT/Methodical/eh/basics/throwinfault.il @@ -10,9 +10,9 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'throwinfault' {} +.class public auto ansi Test_throwinfault extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -79,3 +79,4 @@ ret } +} diff --git a/src/tests/JIT/Methodical/eh/basics/throwinfilter.il b/src/tests/JIT/Methodical/eh/basics/throwinfilter.il index d074b3626393d4..1b84f3a82715d0 100644 --- a/src/tests/JIT/Methodical/eh/basics/throwinfilter.il +++ b/src/tests/JIT/Methodical/eh/basics/throwinfilter.il @@ -10,9 +10,9 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'throwinfilter' {} +.class public auto ansi Test_throwinfilter extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -82,3 +82,4 @@ done2: ret } +} diff --git a/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter1.il b/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter1.il index 89978e47e6456f..474a5bc633802f 100644 --- a/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter1.il +++ b/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter1.il @@ -10,10 +10,10 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'throwinfinallyintryfilter1' {} +.class public auto ansi Test_throwinfinallyintryfilter1 extends [mscorlib] System.Object { .method public static int32 Main() { .entrypoint @@ -78,7 +78,7 @@ ret } - +} .method public static void func(int32 i) { diff --git a/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter2.il b/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter2.il index 7aecdc00490944..ce625c9dc70b5c 100644 --- a/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter2.il +++ b/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter2.il @@ -10,10 +10,10 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'throwinfinallyintryfilter2' {} +.class public auto ansi Test_throwinfinallyintryfilter2 extends [mscorlib] System.Object { .method public static int32 Main() { .entrypoint @@ -78,7 +78,7 @@ ret } - +} .method public static void func(int32 i) { diff --git a/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter3.il b/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter3.il index 10244b655d4ef7..7cbe44cb2474dd 100644 --- a/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter3.il +++ b/src/tests/JIT/Methodical/eh/basics/throwinfinallyintryfilter3.il @@ -10,10 +10,10 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'throwinfinallyintryfilter3' {} +.class public auto ansi Test_throwinfinallyintryfilter3 extends [mscorlib] System.Object { .method public static int32 Main() { .entrypoint @@ -87,7 +87,7 @@ ret } - +} .method public static void func(int32 i) { diff --git a/src/tests/JIT/Methodical/eh/basics/tryexcept.il b/src/tests/JIT/Methodical/eh/basics/tryexcept.il index fe357ac542d8a9..cba5d6f34e0b63 100644 --- a/src/tests/JIT/Methodical/eh/basics/tryexcept.il +++ b/src/tests/JIT/Methodical/eh/basics/tryexcept.il @@ -10,9 +10,9 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'tryexcept' {} +.class public auto ansi Test_tryexcept extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -64,3 +64,4 @@ handler_begin: pop ret .try try_start to filter_begin filter filter_begin handler handler_begin to done } +} diff --git a/src/tests/JIT/Methodical/eh/basics/tryfault.il b/src/tests/JIT/Methodical/eh/basics/tryfault.il index dc09833fb5d20e..6135b17a5960bb 100644 --- a/src/tests/JIT/Methodical/eh/basics/tryfault.il +++ b/src/tests/JIT/Methodical/eh/basics/tryfault.il @@ -10,9 +10,9 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'tryfault' {} +.class public auto ansi Test_tryfault extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -57,3 +57,4 @@ ret } +} diff --git a/src/tests/JIT/Methodical/eh/basics/tryfaulttrycatch.il b/src/tests/JIT/Methodical/eh/basics/tryfaulttrycatch.il index c70b4e281823f0..db1e5585935297 100644 --- a/src/tests/JIT/Methodical/eh/basics/tryfaulttrycatch.il +++ b/src/tests/JIT/Methodical/eh/basics/tryfaulttrycatch.il @@ -10,9 +10,9 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'tryfaulttrycatch' {} +.class public auto ansi Test_tryfaulttrycatch extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -77,3 +77,4 @@ ret } +} diff --git a/src/tests/JIT/Methodical/eh/basics/tryfaulttrycatchfn.il b/src/tests/JIT/Methodical/eh/basics/tryfaulttrycatchfn.il index 85372b3ebe462f..f894a0bc0903cb 100644 --- a/src/tests/JIT/Methodical/eh/basics/tryfaulttrycatchfn.il +++ b/src/tests/JIT/Methodical/eh/basics/tryfaulttrycatchfn.il @@ -10,8 +10,7 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'tryfaulttrycatchfn' {} .method public static void middle() { .maxstack 1 @@ -38,6 +37,7 @@ done: } +.class public auto ansi Test_tryfaulttrycatchfn extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -89,3 +89,4 @@ done: ret } +} diff --git a/src/tests/JIT/Methodical/eh/basics/tryfinallywith2endfinally.il b/src/tests/JIT/Methodical/eh/basics/tryfinallywith2endfinally.il index 10f663b48244fd..d1131b696ded08 100644 --- a/src/tests/JIT/Methodical/eh/basics/tryfinallywith2endfinally.il +++ b/src/tests/JIT/Methodical/eh/basics/tryfinallywith2endfinally.il @@ -38,7 +38,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/basics/tryfinallywith2reachableendfinally.il b/src/tests/JIT/Methodical/eh/basics/tryfinallywith2reachableendfinally.il index f92dc8acf5cbed..99322c0371165b 100644 --- a/src/tests/JIT/Methodical/eh/basics/tryfinallywith2reachableendfinally.il +++ b/src/tests/JIT/Methodical/eh/basics/tryfinallywith2reachableendfinally.il @@ -44,7 +44,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/basics/trythrowexcept.il b/src/tests/JIT/Methodical/eh/basics/trythrowexcept.il index 8365a8178b24e8..b2677021d61f93 100644 --- a/src/tests/JIT/Methodical/eh/basics/trythrowexcept.il +++ b/src/tests/JIT/Methodical/eh/basics/trythrowexcept.il @@ -10,9 +10,9 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} -.module test.exe +.assembly 'trythrowexcept' {} +.class public auto ansi Test_trythrowexcept extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -80,3 +80,4 @@ handler_begin: pop ret .try try_start to filter_begin filter filter_begin handler handler_begin to done } +} diff --git a/src/tests/JIT/Methodical/eh/deadcode/deadcodeincatch.il b/src/tests/JIT/Methodical/eh/deadcode/deadcodeincatch.il index d0fad14bb4304a..38bb6144f35b9d 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/deadcodeincatch.il +++ b/src/tests/JIT/Methodical/eh/deadcode/deadcodeincatch.il @@ -113,7 +113,7 @@ } // end of method Class1::inFinally .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/deadcode/deadnonlocalexit.il b/src/tests/JIT/Methodical/eh/deadcode/deadnonlocalexit.il index 6d828d68e57746..fa1f9d67adf317 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/deadnonlocalexit.il +++ b/src/tests/JIT/Methodical/eh/deadcode/deadnonlocalexit.il @@ -12,16 +12,16 @@ .ver 0:0:0:0 } .assembly extern eh_common{} -.assembly test +.assembly 'deadnonlocalexit' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_deadnonlocalexit extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -90,3 +90,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/deadcode/deadoponerrorinfunclet.il b/src/tests/JIT/Methodical/eh/deadcode/deadoponerrorinfunclet.il index a16deba23f93df..f2c24d3916e13c 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/deadoponerrorinfunclet.il +++ b/src/tests/JIT/Methodical/eh/deadcode/deadoponerrorinfunclet.il @@ -66,7 +66,7 @@ extends [mscorlib]System.Object { .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/deadcode/deadrgninfunclet.il b/src/tests/JIT/Methodical/eh/deadcode/deadrgninfunclet.il index 9b2d35aa284777..50ae427185312a 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/deadrgninfunclet.il +++ b/src/tests/JIT/Methodical/eh/deadcode/deadrgninfunclet.il @@ -13,16 +13,16 @@ .ver 0:0:0:0 } .assembly extern eh_common{} -.assembly test +.assembly 'deadrgninfunclet' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_deadrgninfunclet extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -121,3 +121,4 @@ L5: callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/deadcode/deadtrycatch.il b/src/tests/JIT/Methodical/eh/deadcode/deadtrycatch.il index 949b08ef2f0e8e..ecd0a61840ed76 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/deadtrycatch.il +++ b/src/tests/JIT/Methodical/eh/deadcode/deadtrycatch.il @@ -13,16 +13,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'deadtrycatch' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_deadtrycatch extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -82,3 +82,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/deadcode/deadtryfinally.il b/src/tests/JIT/Methodical/eh/deadcode/deadtryfinally.il index c119f4c4f0292b..e06ea1ed999203 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/deadtryfinally.il +++ b/src/tests/JIT/Methodical/eh/deadcode/deadtryfinally.il @@ -13,16 +13,16 @@ .ver 0:0:0:0 } .assembly extern eh_common{} -.assembly test +.assembly 'deadtryfinally' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_deadtryfinally extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -77,3 +77,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/deadcode/deadtryfinallythrow.il b/src/tests/JIT/Methodical/eh/deadcode/deadtryfinallythrow.il index f435b0a0b4eb67..d06c23e10d1982 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/deadtryfinallythrow.il +++ b/src/tests/JIT/Methodical/eh/deadcode/deadtryfinallythrow.il @@ -13,16 +13,16 @@ .ver 0:0:0:0 } .assembly extern eh_common{} -.assembly test +.assembly 'deadtryfinallythrow' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_deadtryfinallythrow extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -80,3 +80,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/deadcode/severaldeadehregions.il b/src/tests/JIT/Methodical/eh/deadcode/severaldeadehregions.il index 2ea3724d8e6ac8..3a00de9deec06d 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/severaldeadehregions.il +++ b/src/tests/JIT/Methodical/eh/deadcode/severaldeadehregions.il @@ -14,16 +14,16 @@ } .assembly extern eh_common{} -.assembly test +.assembly 'severaldeadehregions' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_severaldeadehregions extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -178,3 +178,4 @@ skip: callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/deadcode/severalnesteddeadehregions.il b/src/tests/JIT/Methodical/eh/deadcode/severalnesteddeadehregions.il index 7aaa1e57ebde63..a8b139717185da 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/severalnesteddeadehregions.il +++ b/src/tests/JIT/Methodical/eh/deadcode/severalnesteddeadehregions.il @@ -13,16 +13,16 @@ .ver 0:0:0:0 } .assembly extern eh_common{} -.assembly test +.assembly 'severalnesteddeadehregions' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_severalnesteddeadehregions extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -177,3 +177,4 @@ skip: callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/deadcode/simpledeadehregion.il b/src/tests/JIT/Methodical/eh/deadcode/simpledeadehregion.il index c4e6421d013c88..cf5b29bd560aa1 100644 --- a/src/tests/JIT/Methodical/eh/deadcode/simpledeadehregion.il +++ b/src/tests/JIT/Methodical/eh/deadcode/simpledeadehregion.il @@ -13,16 +13,16 @@ .ver 0:0:0:0 } .assembly extern eh_common{} -.assembly test +.assembly 'simpledeadehregion' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_simpledeadehregion extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -84,3 +84,4 @@ done: callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/backwardleave.il b/src/tests/JIT/Methodical/eh/disconnected/backwardleave.il index 7156403fc2d853..b92a9417741c1b 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/backwardleave.il +++ b/src/tests/JIT/Methodical/eh/disconnected/backwardleave.il @@ -12,16 +12,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'backwardleave' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_backwardleave extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -89,3 +89,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/catchbeforetrybody.il b/src/tests/JIT/Methodical/eh/disconnected/catchbeforetrybody.il index ad500f16dea8b5..af583048f1e244 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/catchbeforetrybody.il +++ b/src/tests/JIT/Methodical/eh/disconnected/catchbeforetrybody.il @@ -13,16 +13,16 @@ .ver 0:0:0:0 } .assembly extern eh_common{} -.assembly test +.assembly 'catchbeforetrybody' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_catchbeforetrybody extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -75,3 +75,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/catchtryintryfinally.il b/src/tests/JIT/Methodical/eh/disconnected/catchtryintryfinally.il index f9c72946664c31..4396f775fd1d0d 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/catchtryintryfinally.il +++ b/src/tests/JIT/Methodical/eh/disconnected/catchtryintryfinally.il @@ -13,15 +13,15 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'catchtryintryfinally' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_catchtryintryfinally extends [mscorlib] System.Object { .method public static int32 main() cil managed { .entrypoint @@ -87,3 +87,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/faultbeforetrybody.il b/src/tests/JIT/Methodical/eh/disconnected/faultbeforetrybody.il index f50a5d519313fd..d47705c9c032ba 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/faultbeforetrybody.il +++ b/src/tests/JIT/Methodical/eh/disconnected/faultbeforetrybody.il @@ -12,16 +12,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'faultbeforetrybody' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_faultbeforetrybody extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -68,3 +68,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/finallybeforetrybody.il b/src/tests/JIT/Methodical/eh/disconnected/finallybeforetrybody.il index ae83cfb461d6b7..3e402f1435882d 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/finallybeforetrybody.il +++ b/src/tests/JIT/Methodical/eh/disconnected/finallybeforetrybody.il @@ -12,16 +12,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'finallybeforetrybody' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_finallybeforetrybody extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -73,3 +73,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/finallytryintryfinally.il b/src/tests/JIT/Methodical/eh/disconnected/finallytryintryfinally.il index 94dc2f34b74077..84ec50ab372369 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/finallytryintryfinally.il +++ b/src/tests/JIT/Methodical/eh/disconnected/finallytryintryfinally.il @@ -12,16 +12,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'finallytryintryfinally' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_finallytryintryfinally extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 4 @@ -87,3 +87,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/reversedhandlers.il b/src/tests/JIT/Methodical/eh/disconnected/reversedhandlers.il index 3201300295376a..a143fecbb685eb 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/reversedhandlers.il +++ b/src/tests/JIT/Methodical/eh/disconnected/reversedhandlers.il @@ -12,16 +12,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'reversedhandlers' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_reversedhandlers extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -101,3 +101,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/reversedtryblock.il b/src/tests/JIT/Methodical/eh/disconnected/reversedtryblock.il index 2b25d44528ce0f..7cde3539a13abf 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/reversedtryblock.il +++ b/src/tests/JIT/Methodical/eh/disconnected/reversedtryblock.il @@ -12,16 +12,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'reversedtryblock' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_reversedtryblock extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -95,3 +95,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/sehhandlerbeforetry.il b/src/tests/JIT/Methodical/eh/disconnected/sehhandlerbeforetry.il index 9b88eb464c75f5..156f8a59ecb98f 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/sehhandlerbeforetry.il +++ b/src/tests/JIT/Methodical/eh/disconnected/sehhandlerbeforetry.il @@ -12,16 +12,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'sehhandlerbeforetry' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_sehhandlerbeforetry extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -79,3 +79,4 @@ done: .try try_start to try_end filter filter_begin handler handler_begin to handler_end } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/testeit.il b/src/tests/JIT/Methodical/eh/disconnected/testeit.il index 939a9ac6497cac..eda0857b3676f1 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/testeit.il +++ b/src/tests/JIT/Methodical/eh/disconnected/testeit.il @@ -13,16 +13,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'testeit' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_testeit extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -113,3 +113,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/trybodyinbetweencatchhandlers.il b/src/tests/JIT/Methodical/eh/disconnected/trybodyinbetweencatchhandlers.il index 4a7aca0c871c9a..8cb16d7e5f83eb 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/trybodyinbetweencatchhandlers.il +++ b/src/tests/JIT/Methodical/eh/disconnected/trybodyinbetweencatchhandlers.il @@ -13,16 +13,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'trybodyinbetweencatchhandlers' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_trybodyinbetweencatchhandlers extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -173,3 +173,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/disconnected/tryfinallyincatchtry.il b/src/tests/JIT/Methodical/eh/disconnected/tryfinallyincatchtry.il index 24eb60775ab0a8..40da63cd79e572 100644 --- a/src/tests/JIT/Methodical/eh/disconnected/tryfinallyincatchtry.il +++ b/src/tests/JIT/Methodical/eh/disconnected/tryfinallyincatchtry.il @@ -12,16 +12,16 @@ .ver 0:0:0:0 } .assembly extern eh_common {} -.assembly test +.assembly 'tryfinallyincatchtry' { .ver 0:0:0:0 } -.module test.exe .imagebase 0x00400000 .subsystem 0x00000003 .file alignment 512 .corflags 0x00000001 +.class public auto ansi Test_tryfinallyincatchtry extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 400 @@ -103,3 +103,4 @@ callvirt instance int32 [eh_common]TestUtil.TestLog::VerifyOutput() ret } +} diff --git a/src/tests/JIT/Methodical/eh/finallyexec/catchrettoinnertry.il b/src/tests/JIT/Methodical/eh/finallyexec/catchrettoinnertry.il index 045eb725be5491..876d61b6d7cac5 100644 --- a/src/tests/JIT/Methodical/eh/finallyexec/catchrettoinnertry.il +++ b/src/tests/JIT/Methodical/eh/finallyexec/catchrettoinnertry.il @@ -66,7 +66,7 @@ ret } .method private hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/finallyexec/nonlocalexittonestedsibling.il b/src/tests/JIT/Methodical/eh/finallyexec/nonlocalexittonestedsibling.il index c3fd5fd1534940..16b22c14b97f87 100644 --- a/src/tests/JIT/Methodical/eh/finallyexec/nonlocalexittonestedsibling.il +++ b/src/tests/JIT/Methodical/eh/finallyexec/nonlocalexittonestedsibling.il @@ -56,7 +56,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/2branchesoutoftry.il b/src/tests/JIT/Methodical/eh/leaves/2branchesoutoftry.il index fe173773ddcb50..25cd53f9527563 100644 --- a/src/tests/JIT/Methodical/eh/leaves/2branchesoutoftry.il +++ b/src/tests/JIT/Methodical/eh/leaves/2branchesoutoftry.il @@ -38,7 +38,7 @@ extends [mscorlib]System.Object { .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/backwardleaveincatch.il b/src/tests/JIT/Methodical/eh/leaves/backwardleaveincatch.il index 7622150ab520d9..0083d08b13c3d2 100644 --- a/src/tests/JIT/Methodical/eh/leaves/backwardleaveincatch.il +++ b/src/tests/JIT/Methodical/eh/leaves/backwardleaveincatch.il @@ -75,7 +75,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/branchbackwardswithcatch.il b/src/tests/JIT/Methodical/eh/leaves/branchbackwardswithcatch.il index 59dc610160c67f..05affd9b7f7965 100644 --- a/src/tests/JIT/Methodical/eh/leaves/branchbackwardswithcatch.il +++ b/src/tests/JIT/Methodical/eh/leaves/branchbackwardswithcatch.il @@ -74,7 +74,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/branchbackwardswithfinally.il b/src/tests/JIT/Methodical/eh/leaves/branchbackwardswithfinally.il index f1c07aba492b03..127425504c0a7b 100644 --- a/src/tests/JIT/Methodical/eh/leaves/branchbackwardswithfinally.il +++ b/src/tests/JIT/Methodical/eh/leaves/branchbackwardswithfinally.il @@ -74,7 +74,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/branchoutofnestedtryfinally.il b/src/tests/JIT/Methodical/eh/leaves/branchoutofnestedtryfinally.il index b17ba775076758..de2ec0385b8cdd 100644 --- a/src/tests/JIT/Methodical/eh/leaves/branchoutofnestedtryfinally.il +++ b/src/tests/JIT/Methodical/eh/leaves/branchoutofnestedtryfinally.il @@ -83,7 +83,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/branchoutoftryfinally.il b/src/tests/JIT/Methodical/eh/leaves/branchoutoftryfinally.il index 34a79462a7c044..e0c653e4f56164 100644 --- a/src/tests/JIT/Methodical/eh/leaves/branchoutoftryfinally.il +++ b/src/tests/JIT/Methodical/eh/leaves/branchoutoftryfinally.il @@ -39,7 +39,7 @@ extends [mscorlib]System.Object { .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/forwardleaveincatch.il b/src/tests/JIT/Methodical/eh/leaves/forwardleaveincatch.il index 831f8227f79d91..d500275f8d4b90 100644 --- a/src/tests/JIT/Methodical/eh/leaves/forwardleaveincatch.il +++ b/src/tests/JIT/Methodical/eh/leaves/forwardleaveincatch.il @@ -74,7 +74,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/leaveinsameregion.il b/src/tests/JIT/Methodical/eh/leaves/leaveinsameregion.il index 677873d6cc29c7..c6b6aa006c745a 100644 --- a/src/tests/JIT/Methodical/eh/leaves/leaveinsameregion.il +++ b/src/tests/JIT/Methodical/eh/leaves/leaveinsameregion.il @@ -63,7 +63,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/leaveintotrybody.il b/src/tests/JIT/Methodical/eh/leaves/leaveintotrybody.il index 56f4feee5d43c2..8ccab02bdd3b0f 100644 --- a/src/tests/JIT/Methodical/eh/leaves/leaveintotrybody.il +++ b/src/tests/JIT/Methodical/eh/leaves/leaveintotrybody.il @@ -55,7 +55,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/leaves/tryfinallyintrycatchwithleaveintotry.il b/src/tests/JIT/Methodical/eh/leaves/tryfinallyintrycatchwithleaveintotry.il index 8ee803a7a8f21f..6dc5ca240c8c17 100644 --- a/src/tests/JIT/Methodical/eh/leaves/tryfinallyintrycatchwithleaveintotry.il +++ b/src/tests/JIT/Methodical/eh/leaves/tryfinallyintrycatchwithleaveintotry.il @@ -56,7 +56,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/mixedhandler/catchfiltercatch.il b/src/tests/JIT/Methodical/eh/mixedhandler/catchfiltercatch.il index 29dd18a3733828..30b494ed6ae547 100644 --- a/src/tests/JIT/Methodical/eh/mixedhandler/catchfiltercatch.il +++ b/src/tests/JIT/Methodical/eh/mixedhandler/catchfiltercatch.il @@ -54,7 +54,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/mixedhandler/filterfiltercatchcatch.il b/src/tests/JIT/Methodical/eh/mixedhandler/filterfiltercatchcatch.il index 4f64c5669c2ac4..cef244dd43f09c 100644 --- a/src/tests/JIT/Methodical/eh/mixedhandler/filterfiltercatchcatch.il +++ b/src/tests/JIT/Methodical/eh/mixedhandler/filterfiltercatchcatch.il @@ -54,7 +54,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/cascadedcatch.il b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/cascadedcatch.il index 668d73cfc64ede..06991996723210 100644 --- a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/cascadedcatch.il +++ b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/cascadedcatch.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'cascadedcatch' {} -.module cascadedcatch.exe +.class public auto ansi Test_cascadedcatch extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -1497,3 +1497,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/cascadedexcept.il b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/cascadedexcept.il index a402afd45e3a5a..725e8bef97a6c0 100644 --- a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/cascadedexcept.il +++ b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/cascadedexcept.il @@ -8,10 +8,10 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'cascadedexcept' {} -.module cascadedexcept.exe +.class public auto ansi Test_cascadedexcept extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -1839,3 +1839,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedcatch.il b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedcatch.il index 7f2f6392fdd60f..ed1b127a1104c9 100644 --- a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedcatch.il +++ b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedcatch.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'throwincascadedcatch' {} -.module cascadedcatch.exe +.class public auto ansi Test_throwincascadedcatch extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -1677,3 +1677,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedcatchnofin.il b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedcatchnofin.il index 00c8ce18837ce1..6926a841d5b1bf 100644 --- a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedcatchnofin.il +++ b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedcatchnofin.il @@ -8,10 +8,10 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'throwincascadedcatchnofin' {} -.module throwincascadedcatchnofin.exe +.class public auto ansi Test_throwincascadedcatchnofin extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -1856,3 +1856,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedexcept.il b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedexcept.il index 5eaf4dc420665c..212279fe3df530 100644 --- a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedexcept.il +++ b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedexcept.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'throwincascadedexcept' {} -.module throwincascadedexcept.exe +.class public auto ansi Test_throwincascadedexcept extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -2077,3 +2077,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedexceptnofin.il b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedexceptnofin.il index 0602fc15437d8e..c3b5d6ec6a12cd 100644 --- a/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedexceptnofin.il +++ b/src/tests/JIT/Methodical/eh/nested/cascadedcatchret/throwincascadedexceptnofin.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'throwincascadedexceptnofin' {} -.module throwincascadedexceptnofin.exe +.class public auto ansi Test_throwincascadedexceptnofin extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -2357,3 +2357,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/general/localvarincatch.il b/src/tests/JIT/Methodical/eh/nested/general/localvarincatch.il index a5c25e0aae5524..1930bc31678aca 100644 --- a/src/tests/JIT/Methodical/eh/nested/general/localvarincatch.il +++ b/src/tests/JIT/Methodical/eh/nested/general/localvarincatch.il @@ -10,10 +10,10 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'localvarincatch' {} -.module localvarincatch.exe +.class public auto ansi Test_localvarincatch extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -202,3 +202,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtrycatch.il b/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtrycatch.il index 2f8f1c742e7b06..ba1f91c2bf1179 100644 --- a/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtrycatch.il +++ b/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtrycatch.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'nestedtrycatch' {} -.module nestedtrycatch.exe +.class public auto ansi Test_nestedtrycatch extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -649,3 +649,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryexcept.il b/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryexcept.il index 9cf8c25aaf1cd3..948aa07b0e418c 100644 --- a/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryexcept.il +++ b/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryexcept.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'nestedtryexcept' {} -.module nestedtryexcept.exe +.class public auto ansi Test_nestedtryexcept extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -999,3 +999,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryfault.il b/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryfault.il index dead1524514b9d..cb4af7c0a36f17 100644 --- a/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryfault.il +++ b/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryfault.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'nestedtryfault' {} -.module nestedtryfault.exe +.class public auto ansi Test_nestedtryfault extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -599,3 +599,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryfinally.il b/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryfinally.il index 2a196a54c8732b..a5fa0858d87968 100644 --- a/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryfinally.il +++ b/src/tests/JIT/Methodical/eh/nested/nestedtry/nestedtryfinally.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'nestedtryfinally' {} -.module nestedtryfinally.exe +.class public auto ansi Test_nestedtryfinally extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -749,3 +749,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtrycatch.il b/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtrycatch.il index 599ed7436ee8b2..0d5a9b682d2d4f 100644 --- a/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtrycatch.il +++ b/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtrycatch.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'throwinnestedtrycatch' {} -.module throwinnestedtrycatch.exe +.class public auto ansi Test_throwinnestedtrycatch extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -653,3 +653,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryexcept.il b/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryexcept.il index d6058ff3e2b6e1..d7f0f1ed8e91f5 100644 --- a/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryexcept.il +++ b/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryexcept.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'throwinnestedtryexcept' {} -.module throwinnestedtryexcept.exe +.class public auto ansi Test_throwinnestedtryexcept extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -1153,3 +1153,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryfault.il b/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryfault.il index 94ac64ddd8e4f1..8df59bb51b9def 100644 --- a/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryfault.il +++ b/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryfault.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'throwinnestedtryfault' {} -.module throwinnestedtryfault.exe +.class public auto ansi Test_throwinnestedtryfault extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -751,3 +751,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryfinally.il b/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryfinally.il index 08da5fd61dace5..60bd92d039f92a 100644 --- a/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryfinally.il +++ b/src/tests/JIT/Methodical/eh/nested/nestedtry/throwinnestedtryfinally.il @@ -8,11 +8,11 @@ } .assembly extern mscorlib {} .assembly extern eh_common {} -.assembly test {} +.assembly 'throwinnestedtryfinally' {} -.module throwinnestedtryfinally.exe +.class public auto ansi Test_throwinnestedtryfinally extends [mscorlib] System.Object { .method public static int32 main() { .entrypoint .maxstack 2 @@ -751,3 +751,4 @@ begin: ret } +} diff --git a/src/tests/JIT/Methodical/eh/rethrow/rethrowinfinallyinsidecatch.il b/src/tests/JIT/Methodical/eh/rethrow/rethrowinfinallyinsidecatch.il index cbc8f49a802c32..ea985dc848fe70 100644 --- a/src/tests/JIT/Methodical/eh/rethrow/rethrowinfinallyinsidecatch.il +++ b/src/tests/JIT/Methodical/eh/rethrow/rethrowinfinallyinsidecatch.il @@ -54,7 +54,7 @@ } .method public hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_byte_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_byte_1.cs index 91abb660d75297..b5d2439989dbfa 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_byte_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_byte_1.cs @@ -70,15 +70,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_byte_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_double_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_double_1.cs index a96e0985519075..4d1dcfb2b266df 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_double_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_double_1.cs @@ -61,15 +61,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_double_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_float_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_float_1.cs index 3c942595d60c70..fd40bb671dd5ea 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_float_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_float_1.cs @@ -61,15 +61,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_float_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_byte_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_byte_1.cs index 8811b34e6b0865..730bd14261a2cc 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_byte_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_byte_1.cs @@ -64,15 +64,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_gc_byte_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_double_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_double_1.cs index bf77c5c2ee0e7b..4340a506bc44b5 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_double_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_double_1.cs @@ -70,15 +70,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_gc_double_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_float_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_float_1.cs index 1bbc86d2a3031a..5f9070e6c4fd4f 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_float_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_float_1.cs @@ -73,15 +73,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_gc_float_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_int_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_int_1.cs index fdb6897002c77e..38cb7135f3bb82 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_int_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_int_1.cs @@ -64,15 +64,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_gc_int_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_long_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_long_1.cs index c6b7125917b736..fdd41319000450 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_long_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_long_1.cs @@ -61,15 +61,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_gc_long_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_obj_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_obj_1.cs index a17b005371e3a6..8c349930f63765 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_obj_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_obj_1.cs @@ -68,15 +68,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_gc_obj_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_short_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_short_1.cs index f8f913867e924e..ac765a840a062c 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_short_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_short_1.cs @@ -70,15 +70,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_gc_short_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_val_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_val_1.cs index f517ea411ff8bc..884617e275b468 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_gc_val_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_gc_val_1.cs @@ -77,15 +77,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_gc_val_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_int_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_int_1.cs index 0f34a1a3165ef3..9d98877a125d24 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_int_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_int_1.cs @@ -70,15 +70,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_int_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_long_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_long_1.cs index f99ba8ac4965bd..068609bbd90fb5 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_long_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_long_1.cs @@ -73,15 +73,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_long_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_obj_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_obj_1.cs index 2894112f7c0afd..c1dedb69238ac5 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_obj_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_obj_1.cs @@ -77,15 +77,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_obj_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_short_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_short_1.cs index e7cbdb032accf2..7caa6d529e8518 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_short_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_short_1.cs @@ -64,15 +64,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_short_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/expl_val_1.cs b/src/tests/JIT/Methodical/explicit/coverage/expl_val_1.cs index 6f88bd27c8ddb5..e8682218930751 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/expl_val_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/expl_val_1.cs @@ -77,15 +77,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_expl_val_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_byte_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_byte_1.cs index e073fa28d2f11e..d404214ae51d95 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_byte_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_byte_1.cs @@ -61,15 +61,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_byte_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_double_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_double_1.cs index 1de7b7424880cc..25e5206cb73605 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_double_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_double_1.cs @@ -60,15 +60,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_double_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_float_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_float_1.cs index 295747188b4e43..d34d388ddce289 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_float_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_float_1.cs @@ -60,15 +60,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_float_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_byte_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_byte_1.cs index bf8045176af18b..92dcfa3e61fb30 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_byte_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_byte_1.cs @@ -64,15 +64,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_gc_byte_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_double_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_double_1.cs index f8a4162ee238c4..9d1280b0a5f606 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_double_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_double_1.cs @@ -69,15 +69,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_gc_double_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_float_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_float_1.cs index f26d2d0e032dee..39111bb0dfd879 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_float_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_float_1.cs @@ -72,15 +72,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_gc_float_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_int_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_int_1.cs index 17a85ec4099b1c..fdd0899ba15da6 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_int_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_int_1.cs @@ -63,15 +63,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_gc_int_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_long_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_long_1.cs index 5ed705e40ea9e3..4ea49126a39699 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_long_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_long_1.cs @@ -60,15 +60,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_gc_long_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_obj_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_obj_1.cs index b5a9662c83d88f..64d92a0733929e 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_obj_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_obj_1.cs @@ -68,15 +68,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_gc_obj_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_short_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_short_1.cs index a5a154ed96cfeb..73783c84a64655 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_short_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_short_1.cs @@ -70,15 +70,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_gc_short_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_val_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_val_1.cs index 1477a37cf7c5b5..5b4225eff018a2 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_gc_val_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_gc_val_1.cs @@ -77,15 +77,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_gc_val_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_int_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_int_1.cs index 5e8db0c1149e2c..90eb07e50a347f 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_int_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_int_1.cs @@ -69,15 +69,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_int_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_long_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_long_1.cs index 569a1667a5e4f0..424364c1a12358 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_long_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_long_1.cs @@ -72,15 +72,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_long_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_obj_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_obj_1.cs index 31adbca5d69678..64bde845f93c38 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_obj_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_obj_1.cs @@ -77,15 +77,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_obj_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_short_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_short_1.cs index 6afeec7a144f52..103612dca85193 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_short_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_short_1.cs @@ -64,15 +64,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_short_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/explicit/coverage/seq_val_1.cs b/src/tests/JIT/Methodical/explicit/coverage/seq_val_1.cs index 22fcfb105684a7..3d8154ba863000 100644 --- a/src/tests/JIT/Methodical/explicit/coverage/seq_val_1.cs +++ b/src/tests/JIT/Methodical/explicit/coverage/seq_val_1.cs @@ -68,15 +68,18 @@ public static void reset() BB.f_init = new AA(100); BB.f_zero = new AA(0); } +} + +internal struct BB +{ + public static AA f_init, f_zero; +} +public static class Test_seq_val_1 +{ [Fact] public static int TestEntrypoint() { return TestApp.RunAllTests(); } } - -internal struct BB -{ - public static AA f_init, f_zero; -} diff --git a/src/tests/JIT/Methodical/flowgraph/bug619534/twoEndFinallys.il b/src/tests/JIT/Methodical/flowgraph/bug619534/twoEndFinallys.il index df5dc52f71d07a..1d34d53210cc74 100644 --- a/src/tests/JIT/Methodical/flowgraph/bug619534/twoEndFinallys.il +++ b/src/tests/JIT/Methodical/flowgraph/bug619534/twoEndFinallys.il @@ -50,7 +50,7 @@ } // end of method Test::.ctor .method private hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -59,7 +59,8 @@ // Code size 23 (0x17) .maxstack 2 .locals init (class Test_twoEndFinallys V_0) - IL_0000: ldarg.0 + ldc.i4.s 0 + IL_0000: newarr [mscorlib]System.String IL_0001: call class Test_twoEndFinallys Test_twoEndFinallys::TwoEndFinallys(string[]) IL_0006: stloc.0 IL_0007: ldloc.0 diff --git a/src/tests/JIT/Methodical/flowgraph/dev10_bug679008/GCOverReporting.cs b/src/tests/JIT/Methodical/flowgraph/dev10_bug679008/GCOverReporting.cs index 808f6e3899a319..c1a36c5e4ec328 100644 --- a/src/tests/JIT/Methodical/flowgraph/dev10_bug679008/GCOverReporting.cs +++ b/src/tests/JIT/Methodical/flowgraph/dev10_bug679008/GCOverReporting.cs @@ -30,13 +30,14 @@ using System; using System.Runtime.CompilerServices; +using Xunit; -internal struct MB8 +public struct MB8 { public object foo; } -internal class Repro +public class Repro { private static int s_counter; [MethodImpl(MethodImplOptions.NoInlining)] @@ -96,7 +97,8 @@ private static unsafe void DoTest() ConsumeStack(3); } - private static int Main() + [Fact] + public static int TestEntryPoint() { Method(); TrashStack(); diff --git a/src/tests/JIT/Methodical/flowgraph/dev10_bug679008/singleRefField.cs b/src/tests/JIT/Methodical/flowgraph/dev10_bug679008/singleRefField.cs index 7049bea333c73b..216ea7399ffbff 100644 --- a/src/tests/JIT/Methodical/flowgraph/dev10_bug679008/singleRefField.cs +++ b/src/tests/JIT/Methodical/flowgraph/dev10_bug679008/singleRefField.cs @@ -9,13 +9,14 @@ using System; using System.Runtime.CompilerServices; +using Xunit; -internal struct MB8 +public struct MB8 { public object foo; } -internal class Repro +public class Repro { private int _state = 1; @@ -66,7 +67,8 @@ private int Bug(MB8 mb8, string V_2) return loc0; } - private static int Main() + [Fact] + public static int TestEntryPoint() { new Repro().Bug(new MB8(), "Test"); return 100; diff --git a/src/tests/JIT/Methodical/inlining/dev10_bug719093/variancesmall.il b/src/tests/JIT/Methodical/inlining/dev10_bug719093/variancesmall.il index 65bea4b23998b7..6b2bb0bade8224 100644 --- a/src/tests/JIT/Methodical/inlining/dev10_bug719093/variancesmall.il +++ b/src/tests/JIT/Methodical/inlining/dev10_bug719093/variancesmall.il @@ -290,7 +290,7 @@ } .method private hidebysig static int32 - Main(string[] args) cil managed + Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/ldtoken/types.il b/src/tests/JIT/Methodical/ldtoken/types.il index 1504f0e2f7bdda..8cecaee7b3560d 100644 --- a/src/tests/JIT/Methodical/ldtoken/types.il +++ b/src/tests/JIT/Methodical/ldtoken/types.il @@ -13,6 +13,8 @@ .class private auto ansi beforefieldinit Test extends [mscorlib]System.Object { + .field private static int32 s_exitCode; + .method private hidebysig static void test_token(object boxed_vt, valuetype [mscorlib]System.RuntimeTypeHandle vt) cil managed @@ -33,7 +35,7 @@ call string [mscorlib]System.String::Concat(string, string) call void [System.Console]System.Console::WriteLine(string) ldc.i4.s 101 - call void [System.Runtime.Extensions]System.Environment::Exit(int32) + stsfld int32 JitTest.Test::s_exitCode IL_EXIT: ret } @@ -45,6 +47,8 @@ ) .entrypoint .maxstack 8 + ldc.i4 100 + stsfld int32 JitTest.Test::s_exitCode ldc.i4.1 box [mscorlib]System.Byte ldtoken [mscorlib]System.Byte @@ -195,7 +199,7 @@ ldstr "Passed" call void [System.Console]System.Console::WriteLine(string) - ldc.i4.s 100 + ldsfld int32 JitTest.Test::s_exitCode ret } .method public hidebysig specialname rtspecialname diff --git a/src/tests/JIT/Methodical/nonvirtualcall/classic.il b/src/tests/JIT/Methodical/nonvirtualcall/classic.il index 58ad342c484d44..6eaeded7ecc146 100644 --- a/src/tests/JIT/Methodical/nonvirtualcall/classic.il +++ b/src/tests/JIT/Methodical/nonvirtualcall/classic.il @@ -681,7 +681,7 @@ IL_000e: ret } // end of method Program::CallFromInsideGrandChild - .method public hidebysig static int32 Main(string[] args) cil managed + .method public hidebysig static int32 Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/nonvirtualcall/delegate.il b/src/tests/JIT/Methodical/nonvirtualcall/delegate.il index 91b24d2723fad5..00a20015f576c6 100644 --- a/src/tests/JIT/Methodical/nonvirtualcall/delegate.il +++ b/src/tests/JIT/Methodical/nonvirtualcall/delegate.il @@ -566,7 +566,7 @@ IL_007f: ret } // end of method Program::CallDelegateFromGrandChild - .method public hidebysig static int32 Main(string[] args) cil managed + .method public hidebysig static int32 Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/nonvirtualcall/generics.il b/src/tests/JIT/Methodical/nonvirtualcall/generics.il index 1a23c734a0e143..9bbb9f408d822c 100644 --- a/src/tests/JIT/Methodical/nonvirtualcall/generics.il +++ b/src/tests/JIT/Methodical/nonvirtualcall/generics.il @@ -693,7 +693,7 @@ IL_000e: ret } // end of method Program::CallFromInsideGrandChild - .method public hidebysig static int32 Main(string[] args) cil managed + .method public hidebysig static int32 Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/nonvirtualcall/generics2.il b/src/tests/JIT/Methodical/nonvirtualcall/generics2.il index 59635af68e3bda..c75da589bb866f 100644 --- a/src/tests/JIT/Methodical/nonvirtualcall/generics2.il +++ b/src/tests/JIT/Methodical/nonvirtualcall/generics2.il @@ -728,7 +728,7 @@ IL_000e: ret } // end of method Program::CallFromInsideGrandChild - .method public hidebysig static int32 Main(string[] args) cil managed + .method public hidebysig static int32 Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/nonvirtualcall/tailcall.il b/src/tests/JIT/Methodical/nonvirtualcall/tailcall.il index 9bbb008aa5de52..959f4fb2a3c504 100644 --- a/src/tests/JIT/Methodical/nonvirtualcall/tailcall.il +++ b/src/tests/JIT/Methodical/nonvirtualcall/tailcall.il @@ -601,7 +601,7 @@ IL_000e: ret } // end of method Program::CallFromInsideGrandChild - .method public hidebysig static int32 Main(string[] args) cil managed + .method public hidebysig static int32 Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/nonvirtualcall/valuetype.il b/src/tests/JIT/Methodical/nonvirtualcall/valuetype.il index 25897d22e79400..44bc21e2a79750 100644 --- a/src/tests/JIT/Methodical/nonvirtualcall/valuetype.il +++ b/src/tests/JIT/Methodical/nonvirtualcall/valuetype.il @@ -114,7 +114,7 @@ IL_0037: ret } // end of method Program::CallDummy - .method public hidebysig static int32 Main(string[] args) cil managed + .method public hidebysig static int32 Main() cil managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 diff --git a/src/tests/JIT/Methodical/stringintern/_XModuletest1-xmod.csproj b/src/tests/JIT/Methodical/stringintern/_XModuletest1-xmod.csproj deleted file mode 100644 index f59521a9207170..00000000000000 --- a/src/tests/JIT/Methodical/stringintern/_XModuletest1-xmod.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - Exe - 1 - - - PdbOnly - - - - - - - - - diff --git a/src/tests/JIT/Methodical/stringintern/_XModuletest2-xmod.csproj b/src/tests/JIT/Methodical/stringintern/_XModuletest2-xmod.csproj deleted file mode 100644 index 1129c074b6cca7..00000000000000 --- a/src/tests/JIT/Methodical/stringintern/_XModuletest2-xmod.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - Exe - 1 - - - PdbOnly - - - - - - - - - diff --git a/src/tests/JIT/Methodical/stringintern/_XModuletest4-xmod.csproj b/src/tests/JIT/Methodical/stringintern/_XModuletest4-xmod.csproj deleted file mode 100644 index b0557586892f3f..00000000000000 --- a/src/tests/JIT/Methodical/stringintern/_XModuletest4-xmod.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - Exe - 1 - - - PdbOnly - - - - - - - - - diff --git a/src/tests/JIT/Methodical/stringintern/test1-xassem.csproj b/src/tests/JIT/Methodical/stringintern/test1-xassem.csproj index 3649fa4a6e01c0..d13649957b9548 100644 --- a/src/tests/JIT/Methodical/stringintern/test1-xassem.csproj +++ b/src/tests/JIT/Methodical/stringintern/test1-xassem.csproj @@ -2,6 +2,7 @@ Exe 1 + $(DefineConstants);XASSEM diff --git a/src/tests/JIT/Methodical/stringintern/test1.cs b/src/tests/JIT/Methodical/stringintern/test1.cs index d64bfce3c16b5f..cff1c451332ee5 100644 --- a/src/tests/JIT/Methodical/stringintern/test1.cs +++ b/src/tests/JIT/Methodical/stringintern/test1.cs @@ -6,7 +6,12 @@ using System; using System.Runtime.CompilerServices; -class Test1 +class +#if XASSEM +Test1_xassem +#else +Test1 +#endif { public static string teststr1 = "static \uC09C\u7B8B field"; public static string[] teststr2 = new string[] { "\u3F2Aarray element 0", "array element 1\uCB53", "array \u47BBelement 2" }; diff --git a/src/tests/JIT/Methodical/stringintern/test2-xassem.csproj b/src/tests/JIT/Methodical/stringintern/test2-xassem.csproj index 01469b76fa3099..3cc83343c7ea99 100644 --- a/src/tests/JIT/Methodical/stringintern/test2-xassem.csproj +++ b/src/tests/JIT/Methodical/stringintern/test2-xassem.csproj @@ -2,6 +2,7 @@ Exe 1 + $(DefineConstants);XASSEM diff --git a/src/tests/JIT/Methodical/stringintern/test2.cs b/src/tests/JIT/Methodical/stringintern/test2.cs index cd5ac6b824e854..2c088ec8f1651d 100644 --- a/src/tests/JIT/Methodical/stringintern/test2.cs +++ b/src/tests/JIT/Methodical/stringintern/test2.cs @@ -6,7 +6,12 @@ using System; using System.Runtime.CompilerServices; -class Test2 +class +#if XASSEM +Test2_xassem +#else +Test2 +#endif { public static string[] teststr2 = new string[] { "\u3F2Aarray element 0", "array element 1\uCB53", "array \u47BBelement 2" }; diff --git a/src/tests/JIT/Methodical/stringintern/test4-xassem.csproj b/src/tests/JIT/Methodical/stringintern/test4-xassem.csproj index 0a8f1dbf9eb01d..6434c9b70af1d3 100644 --- a/src/tests/JIT/Methodical/stringintern/test4-xassem.csproj +++ b/src/tests/JIT/Methodical/stringintern/test4-xassem.csproj @@ -2,6 +2,7 @@ Exe 1 + $(DefineConstants);XASSEM diff --git a/src/tests/JIT/Methodical/stringintern/test4.cs b/src/tests/JIT/Methodical/stringintern/test4.cs index eb6b0dde88dad2..927d16da442a77 100644 --- a/src/tests/JIT/Methodical/stringintern/test4.cs +++ b/src/tests/JIT/Methodical/stringintern/test4.cs @@ -6,7 +6,12 @@ using System; using System.Runtime.CompilerServices; -class Test4 +class +#if XASSEM +Test4_xassem +#else +Test4 +#endif { public static string teststr1 = null; public static string[] teststr2 = new string[3]; diff --git a/src/tests/JIT/Methodical/switch/switch1.il b/src/tests/JIT/Methodical/switch/switch1.il index 457545a27d577e..b61c08a4b373f9 100644 --- a/src/tests/JIT/Methodical/switch/switch1.il +++ b/src/tests/JIT/Methodical/switch/switch1.il @@ -17,6 +17,8 @@ .class public auto ansi Test_switch1 extends ['mscorlib']System.Object { + .field private static int32 s_exitCode; + .method private hidebysig static void DoSwitch(int32 'value') il managed { .maxstack 2 @@ -32,7 +34,7 @@ IL_0012: br.s IL_0033 IL_0014: ldc.i4.s 100 - IL_0016: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0016: stsfld int32 Test_switch1::s_exitCode IL_001b: ldstr "Test passed" IL_0020: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0025: br.s IL_003f @@ -48,7 +50,7 @@ IL_003f: ret } - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -57,8 +59,7 @@ .maxstack 8 IL_0000: ldc.i4.1 IL_0001: call void Test_switch1::DoSwitch(int32) - IL_0006: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + IL_0006: ldsfld int32 Test_switch1::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch10.il b/src/tests/JIT/Methodical/switch/switch10.il index d311704468b375..cc3d4aaec78b74 100644 --- a/src/tests/JIT/Methodical/switch/switch10.il +++ b/src/tests/JIT/Methodical/switch/switch10.il @@ -17,6 +17,8 @@ .class public auto ansi Test_switch10 extends ['mscorlib']System.Object { + .field private static int32 s_exitCode; + .method private hidebysig static int32 Square(int32 i) il managed { @@ -59,19 +61,19 @@ IL_0018: bne.un.s IL_002d IL_001a: ldc.i4.s 100 - IL_001c: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_001c: stsfld int32 Test_switch10::s_exitCode IL_0021: ldstr "Test passed" IL_0026: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_002b: br.s IL_003d IL_002d: ldc.i4.1 - IL_002e: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_002e: stsfld int32 Test_switch10::s_exitCode IL_0033: ldstr "Test failed" IL_0038: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_003d: ret } - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -80,8 +82,7 @@ .maxstack 8 IL_0000: ldc.i4.1 IL_0001: call void Test_switch10::DoSwitch(int32) - IL_0006: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + IL_0006: ldsfld int32 Test_switch10::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch11.il b/src/tests/JIT/Methodical/switch/switch11.il index 65b37b0b9d7783..b3400c1a557737 100644 --- a/src/tests/JIT/Methodical/switch/switch11.il +++ b/src/tests/JIT/Methodical/switch/switch11.il @@ -17,7 +17,9 @@ .class public auto ansi Test_switch11 extends ['mscorlib']System.Object { - .method public hidebysig static void Main() il managed + .field private static int32 s_exitCode; + + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -30,12 +32,11 @@ IL_0002: br.s IL_0004 IL_0004: ldc.i4.s 100 - IL_0006: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0006: stsfld int32 Test_switch11::s_exitCode IL_000b: ldstr "Test passed" IL_0010: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0015: pop - call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + ldsfld int32 Test_switch11::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch2.il b/src/tests/JIT/Methodical/switch/switch2.il index 382874a80dd4c4..d9b824fb672271 100644 --- a/src/tests/JIT/Methodical/switch/switch2.il +++ b/src/tests/JIT/Methodical/switch/switch2.il @@ -16,6 +16,8 @@ .class public auto ansi Test_switch2 extends ['mscorlib']System.Object { + .field private static int32 s_exitCode; + .method private hidebysig static void DoSwitch(int32 'value') il managed { .maxstack 2 @@ -46,7 +48,7 @@ IL_001e: bne.un.s IL_0031 IL_0020: ldc.i4.s 100 - IL_0022: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0022: stsfld int32 Test_switch2::s_exitCode IL_0027: ldstr "Test passed" IL_002c: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0031: br.s IL_005f @@ -60,13 +62,13 @@ IL_0039: bne.un.s IL_004b IL_003b: ldc.i4.1 - IL_003c: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_003c: stsfld int32 Test_switch2::s_exitCode IL_0041: ldstr "Test failed" IL_0046: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_004b: br.s IL_005f IL_004d: ldc.i4.1 - IL_004e: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_004e: stsfld int32 Test_switch2::s_exitCode IL_0053: ldstr "Test failed" IL_0058: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_005d: br.s IL_005f @@ -74,7 +76,7 @@ IL_005f: ret } - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -83,8 +85,7 @@ .maxstack 8 IL_0000: ldc.i4.1 IL_0001: call void Test_switch2::DoSwitch(int32) - IL_0006: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + ldsfld int32 Test_switch2::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch3.il b/src/tests/JIT/Methodical/switch/switch3.il index 9f253eb5291659..c72351a99c14c0 100644 --- a/src/tests/JIT/Methodical/switch/switch3.il +++ b/src/tests/JIT/Methodical/switch/switch3.il @@ -17,6 +17,8 @@ .class public auto ansi Test_switch3 extends ['mscorlib']System.Object { + .field private static int32 s_exitCode; + .method private hidebysig static void DoSwitch(int32 'value') il managed { .maxstack 2 @@ -34,13 +36,13 @@ IL_0014: br.s IL_0016 IL_0016: ldc.i4.s 100 - IL_0018: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0018: stsfld int32 Test_switch3::s_exitCode IL_001d: ldstr "Test passed" IL_0022: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0027: br.s IL_003b IL_0029: ldc.i4.1 - IL_002a: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_002a: stsfld int32 Test_switch3::s_exitCode IL_002f: ldstr "Test failed" IL_0034: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0039: br.s IL_003b @@ -48,7 +50,7 @@ IL_003b: ret } - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -57,8 +59,7 @@ .maxstack 8 IL_0000: ldc.i4.1 IL_0001: call void Test_switch3::DoSwitch(int32) - IL_0006: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + ldsfld int32 Test_switch3::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch4.il b/src/tests/JIT/Methodical/switch/switch4.il index d8b6ee9b9997fd..2fde7dc43f5100 100644 --- a/src/tests/JIT/Methodical/switch/switch4.il +++ b/src/tests/JIT/Methodical/switch/switch4.il @@ -17,6 +17,7 @@ .class public auto ansi Test_switch4 extends ['mscorlib']System.Object { + .field private static int32 s_exitCode; .field public static int32 count .method private hidebysig static void DoSwitch(int32 'value') il managed { @@ -58,19 +59,19 @@ IL_002e: bne.un.s IL_0043 IL_0030: ldc.i4.s 100 - IL_0032: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0032: stsfld int32 Test_switch4::s_exitCode IL_0037: ldstr "Test passed" IL_003c: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0041: br.s IL_0053 IL_0043: ldc.i4.1 - IL_0044: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0044: stsfld int32 Test_switch4::s_exitCode IL_0049: ldstr "Test failed" IL_004e: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0053: ret } - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -79,8 +80,7 @@ .maxstack 8 IL_0000: ldc.i4.1 IL_0001: call void Test_switch4::DoSwitch(int32) - IL_0006: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + ldsfld int32 Test_switch4::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch5.il b/src/tests/JIT/Methodical/switch/switch5.il index 0bd7a6d4981946..228bd95a818287 100644 --- a/src/tests/JIT/Methodical/switch/switch5.il +++ b/src/tests/JIT/Methodical/switch/switch5.il @@ -17,6 +17,7 @@ .class public auto ansi TestStack extends ['mscorlib']System.Object { + .field public static int32 s_exitCode; .field public int32[] Stack .field public int32 top .method public hidebysig instance void @@ -58,13 +59,13 @@ IL_003c: brtrue.s IL_0051 IL_003e: ldc.i4.s 100 - IL_0040: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0040: stsfld int32 TestStack::s_exitCode IL_0045: ldstr "Test passed" IL_004a: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_004f: br.s IL_0061 IL_0051: ldc.i4.1 - IL_0052: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0052: stsfld int32 TestStack::s_exitCode IL_0057: ldstr "Test failed" IL_005c: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0061: br.s IL_0063 @@ -139,7 +140,7 @@ .class public auto ansi Test_switch5 extends ['mscorlib']System.Object { - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -161,8 +162,7 @@ IL_001b: ldloc.0 IL_001c: ldc.i4.3 IL_001d: call instance void TestStack::DoSwitch(int32) - IL_0022: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + ldsfld int32 TestStack::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch6.il b/src/tests/JIT/Methodical/switch/switch6.il index 91febaea8ec713..898b185fb4152b 100644 --- a/src/tests/JIT/Methodical/switch/switch6.il +++ b/src/tests/JIT/Methodical/switch/switch6.il @@ -18,6 +18,8 @@ .class public auto ansi Test_switch6 extends ['mscorlib']System.Object { + .field private static int32 s_exitCode; + .method private hidebysig static void DoSwitch(int32 'value') il managed { .maxstack 2 @@ -68,19 +70,19 @@ IL_002f: bne.un.s IL_0044 IL_0031: ldc.i4.s 100 - IL_0033: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0033: stsfld int32 Test_switch6::s_exitCode IL_0038: ldstr "Test passed" IL_003d: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0042: br.s IL_0054 IL_0044: ldc.i4.1 - IL_0045: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0045: stsfld int32 Test_switch6::s_exitCode IL_004a: ldstr "Test failed" IL_004f: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0054: ret } - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -89,8 +91,7 @@ .maxstack 8 IL_0000: ldc.i4.1 IL_0001: call void Test_switch6::DoSwitch(int32) - IL_0006: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + ldsfld int32 Test_switch6::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch7.il b/src/tests/JIT/Methodical/switch/switch7.il index 245ff69132b222..e5c0c7e2c5c05f 100644 --- a/src/tests/JIT/Methodical/switch/switch7.il +++ b/src/tests/JIT/Methodical/switch/switch7.il @@ -17,6 +17,7 @@ .class public auto ansi Test_switch7 extends ['mscorlib']System.Object { + .field private static int32 s_exitCode; .field private static int32 count .method private hidebysig static void DoSwitch(int32 'value') il managed { @@ -56,7 +57,7 @@ IL_0044: ret } - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -83,17 +84,16 @@ IL_0018: bne.un.s IL_002d IL_001a: ldc.i4.s 100 - IL_001c: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_001c: stsfld int32 Test_switch7::s_exitCode IL_0021: ldstr "Test passed" IL_0026: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_002b: br.s IL_003d IL_002d: ldc.i4.1 - IL_002e: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_002e: stsfld int32 Test_switch7::s_exitCode IL_0033: ldstr "Test failed" IL_0038: call void ['mscorlib']System.Console::WriteLine(class System.String) - IL_003d: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + IL_003d: ldsfld int32 Test_switch7::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch8.il b/src/tests/JIT/Methodical/switch/switch8.il index e0c38194c09218..c6b0ea8ee568ed 100644 --- a/src/tests/JIT/Methodical/switch/switch8.il +++ b/src/tests/JIT/Methodical/switch/switch8.il @@ -17,6 +17,8 @@ .class public auto ansi Test_switch8 extends ['mscorlib']System.Object { + .field private static int32 s_exitCode; + .method private hidebysig static void DoSwitch(int32 'value') il managed { .maxstack 2 @@ -38,19 +40,19 @@ IL_0018: br.s IL_002d IL_001a: ldc.i4.s 100 - IL_001c: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_001c: stsfld int32 Test_switch8::s_exitCode IL_0021: ldstr "Test passed" IL_0026: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_002b: br.s IL_003d IL_002d: ldc.i4.1 - IL_002e: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_002e: stsfld int32 Test_switch8::s_exitCode IL_0033: ldstr "Test failed" IL_0038: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_003d: ret } - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -59,8 +61,7 @@ .maxstack 8 IL_0000: ldc.i4.2 IL_0001: call void Test_switch8::DoSwitch(int32) - IL_0006: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + ldsfld int32 Test_switch8::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/switch/switch9.il b/src/tests/JIT/Methodical/switch/switch9.il index 7cafa1dd0c033a..a37b14642f7849 100644 --- a/src/tests/JIT/Methodical/switch/switch9.il +++ b/src/tests/JIT/Methodical/switch/switch9.il @@ -17,6 +17,8 @@ .class public auto ansi Test_switch9 extends ['mscorlib']System.Object { + .field private static int32 s_exitCode; + .method private hidebysig static void DoSwitch(int32 val1, int32 val2) il managed { @@ -43,19 +45,19 @@ IL_0026: br.s IL_004d IL_0028: ldc.i4.s 100 - IL_002a: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_002a: stsfld int32 Test_switch9::s_exitCode IL_002f: ldstr "Test passed" IL_0034: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0039: br.s IL_005f IL_003b: ldc.i4.1 - IL_003c: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_003c: stsfld int32 Test_switch9::s_exitCode IL_0041: ldstr "Test failed" IL_0046: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_004b: br.s IL_005f IL_004d: ldc.i4.1 - IL_004e: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_004e: stsfld int32 Test_switch9::s_exitCode IL_0053: ldstr "Test failed" IL_0058: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_005d: br.s IL_005f @@ -63,13 +65,13 @@ IL_005f: br.s IL_0085 IL_0061: ldc.i4.1 - IL_0062: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0062: stsfld int32 Test_switch9::s_exitCode IL_0067: ldstr "Test failed" IL_006c: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0071: br.s IL_0085 IL_0073: ldc.i4.1 - IL_0074: call void ['System.Runtime.Extensions']System.Environment::set_ExitCode(int32) + IL_0074: stsfld int32 Test_switch9::s_exitCode IL_0079: ldstr "Test failed" IL_007e: call void ['mscorlib']System.Console::WriteLine(class System.String) IL_0083: br.s IL_0085 @@ -77,7 +79,7 @@ IL_0085: ret } - .method public hidebysig static void Main() il managed + .method public hidebysig static int32 Main() il managed { .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = ( 01 00 00 00 @@ -88,8 +90,7 @@ IL_0001: ldc.i4.1 IL_0002: call void Test_switch9::DoSwitch(int32, int32) - IL_0007: call int32 ['System.Runtime.Extensions']System.Environment::get_ExitCode() - call void ['System.Runtime.Extensions']System.Environment::Exit(int32) + ldsfld int32 Test_switch9::s_exitCode ret } diff --git a/src/tests/JIT/Methodical/tailcall/test_implicit.il b/src/tests/JIT/Methodical/tailcall/test_implicit.il index 874c079270be45..e24bfe5a0b0ce5 100644 --- a/src/tests/JIT/Methodical/tailcall/test_implicit.il +++ b/src/tests/JIT/Methodical/tailcall/test_implicit.il @@ -26,6 +26,7 @@ .class public auto ansi beforefieldinit Class1 extends [mscorlib]System.Object { + .field private static bool s_failure .field private static int32 MaxDepth .field private int32 'value' .method public hidebysig instance int32 @@ -33,6 +34,9 @@ { .maxstack 5 .locals init (int32 V_0) + ldsfld bool Class1::s_failure + brtrue.s IL_0003 + IL_0000: ldarg.1 IL_0001: brtrue.s IL_000c @@ -91,6 +95,9 @@ ret .maxstack 4 .locals init (string V_0, int32 V_1) + ldsfld bool Class1::s_failure + brtrue.s IL_0003 + IL_0000: ldarg.1 IL_0001: brtrue.s IL_000c @@ -122,8 +129,10 @@ ret IL_0039: call void [System.Console]System.Console::WriteLine(string) IL_003e: ldstr "Test Failed" IL_0043: call void [System.Console]System.Console::WriteLine(string) - IL_0048: ldc.i4.0 - IL_0049: call void [System.Runtime.Extensions]System.Environment::Exit(int32) + IL_0048: ldc.i4.1 + stsfld bool Class1::s_failure + br.s IL_0003 + IL_004e: call void [mscorlib]System.GC::Collect() IL_0053: ldarg.0 IL_0054: dup @@ -155,6 +164,9 @@ ret { .maxstack 5 .locals init (int32 V_0) + ldsfld bool Class1::s_failure + brtrue.s IL_0003 + IL_0000: ldarg.1 IL_0001: brtrue.s IL_000c @@ -209,6 +221,9 @@ ret .maxstack 4 .locals init (string V_0, int32 V_1) + ldsfld bool Class1::s_failure + brtrue.s IL_0003 + IL_0000: ldarg.1 IL_0001: brtrue.s IL_000c @@ -241,8 +256,10 @@ ret IL_0041: call void [System.Console]System.Console::WriteLine(string) IL_0046: ldstr "Test Failed" IL_004b: call void [System.Console]System.Console::WriteLine(string) - IL_0050: ldc.i4.0 - IL_0051: call void [System.Runtime.Extensions]System.Environment::Exit(int32) + IL_0050: ldc.i4.1 + stsfld bool Class1::s_failure + br.s IL_0003 + IL_0056: ldarg.0 IL_0057: dup IL_0058: ldfld int32 Class1::'value' @@ -287,6 +304,9 @@ ret IL_0011: ldsfld int32 Class1::MaxDepth IL_0016: callvirt instance int32 Class1::Recurse1(int32) IL_001b: pop + ldsfld bool Class1::s_failure + brtrue.s IL_0060 + IL_001c: ldc.i4 41963520 IL_001d: stloc.1 IL_001e: ldloc.0 diff --git a/src/tests/JIT/Methodical/xxblk/cpblk3.il b/src/tests/JIT/Methodical/xxblk/cpblk3.il index 1cfda13f8338a2..8f6255949fdb64 100644 --- a/src/tests/JIT/Methodical/xxblk/cpblk3.il +++ b/src/tests/JIT/Methodical/xxblk/cpblk3.il @@ -9,7 +9,7 @@ .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) .ver 4:0:0:0 } -.assembly cpblk2 {} +.assembly 'cpblk3' {} .class public explicit ansi sealed $MultiByte$size$34 extends [mscorlib]System.ValueType { diff --git a/src/tests/JIT/Methodical/xxblk/dynblk_order.il b/src/tests/JIT/Methodical/xxblk/dynblk_order.il index f4d24714c31ade..ebb24d49d1bddf 100644 --- a/src/tests/JIT/Methodical/xxblk/dynblk_order.il +++ b/src/tests/JIT/Methodical/xxblk/dynblk_order.il @@ -7,7 +7,7 @@ .assembly extern System.Console { } .assembly extern xunit.core {} -.assembly DynBlkOrder {} +.assembly 'dynblk_order' {} .typedef [System.Runtime]System.OverflowException as OverflowException .typedef [System.Runtime]System.IndexOutOfRangeException as IndexOutOfRangeException diff --git a/src/tests/JIT/Methodical/xxblk/initblk3.il b/src/tests/JIT/Methodical/xxblk/initblk3.il index e97d7f6ae695f0..dbd4c09bb4a295 100644 --- a/src/tests/JIT/Methodical/xxblk/initblk3.il +++ b/src/tests/JIT/Methodical/xxblk/initblk3.il @@ -9,8 +9,7 @@ .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) .ver 4:0:0:0 } -.assembly initblk2 {} -.module initblk2.exe +.assembly 'initblk3' {} .class public explicit ansi sealed $MultiByte$size$5000 extends [mscorlib]System.ValueType { diff --git a/src/tests/JIT/opt/ForwardSub/callArgInterference.cs b/src/tests/JIT/opt/ForwardSub/callArgInterference.cs new file mode 100644 index 00000000000000..60c8a908e85bc2 --- /dev/null +++ b/src/tests/JIT/opt/ForwardSub/callArgInterference.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Generated by Fuzzlyn v1.5 on 2022-02-02 18:45:57 +// Run on X86 Windows +// Seed: 2552302029114048182 +// Reduced from 26.6 KiB to 0.5 KiB in 00:00:36 +// Debug: Outputs -1 +// Release: Outputs -2 +using System; +using System.Runtime.CompilerServices; + +public interface I1 +{ +} + +public struct S0 : I1 +{ + public static bool result; + public short F5; + public S0(short f5): this() + { + F5 = f5; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public void M4(short arg0, I1 arg1) + { + result = arg0 == -1; + } + + public I1 M7() + { + ref S0 var0 = ref this; + var0 = new S0(1); + return this; + } +} + +public class ForwardSubCallArgInterference +{ + public static IRT s_rt; + public static int Main() + { + s_rt = new C(); + S0 vr0 = default(S0); + new S0(0).M4((short)~vr0.F5, vr0.M7()); + return S0.result ? 100 : -1; + } +} + +public interface IRT +{ + void WriteLine(T val); +} + +public class C : IRT +{ + public void WriteLine(T val) + { + Console.WriteLine(val); + } +} diff --git a/src/tests/JIT/opt/ForwardSub/callArgInterference.csproj b/src/tests/JIT/opt/ForwardSub/callArgInterference.csproj new file mode 100644 index 00000000000000..19781e26c20d81 --- /dev/null +++ b/src/tests/JIT/opt/ForwardSub/callArgInterference.csproj @@ -0,0 +1,10 @@ + + + Exe + + True + + + + + diff --git a/src/tests/JIT/opt/ForwardSub/normalizeOnStore.cs b/src/tests/JIT/opt/ForwardSub/normalizeOnStore.cs new file mode 100644 index 00000000000000..f952758e42e08d --- /dev/null +++ b/src/tests/JIT/opt/ForwardSub/normalizeOnStore.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Note: This test file is the source of the normalizeOnStore.il file. It requires +// InlineIL.Fody to compile. It is not used as anything but a reference of that +// IL file. + +using System; +using System.Runtime.CompilerServices; +using InlineIL; + +class ForwardSubNormalizeOnStore +{ + [MethodImpl(MethodImplOptions.NoInlining)] + private static int Problem(int a) + { + IL.DeclareLocals(new LocalVar(typeof(short))); + + IL.Emit.Ldarg(0); + IL.Emit.Stloc(0); + + IL.Emit.Ldloc(0); + return IL.Return(); + } + + public static int Main() + { + return Problem(0xF0000 + 100); + } +} diff --git a/src/tests/JIT/opt/ForwardSub/normalizeOnStore.il b/src/tests/JIT/opt/ForwardSub/normalizeOnStore.il new file mode 100644 index 00000000000000..6416e7492eaea2 --- /dev/null +++ b/src/tests/JIT/opt/ForwardSub/normalizeOnStore.il @@ -0,0 +1,95 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 +// Copyright (c) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v4.0.30319 +.assembly extern System.Runtime +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: + .ver 6:0:0:0 +} +.assembly store +{ + .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [System.Runtime]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [System.Runtime]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Runtime]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) + + .custom instance void [System.Runtime]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 18 2E 4E 45 54 43 6F 72 65 41 70 70 2C 56 // ....NETCoreApp,V + 65 72 73 69 6F 6E 3D 76 36 2E 30 01 00 54 0E 14 // ersion=v6.0..T.. + 46 72 61 6D 65 77 6F 72 6B 44 69 73 70 6C 61 79 // FrameworkDisplay + 4E 61 6D 65 00 ) // Name. + .custom instance void [System.Runtime]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 05 73 74 6F 72 65 00 00 ) // ...store.. + .custom instance void [System.Runtime]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 07 52 65 6C 65 61 73 65 00 00 ) // ...Release.. + .custom instance void [System.Runtime]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 ) // ...1.0.0.0.. + .custom instance void [System.Runtime]System.Reflection.AssemblyInformationalVersionAttribute::.ctor(string) = ( 01 00 05 31 2E 30 2E 30 00 00 ) // ...1.0.0.. + .custom instance void [System.Runtime]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 05 73 74 6F 72 65 00 00 ) // ...store.. + .custom instance void [System.Runtime]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 05 73 74 6F 72 65 00 00 ) // ...store.. + .hash algorithm 0x00008004 + .ver 1:0:0:0 +} +.module store.dll +// MVID: {A3A2457C-4D44-404C-9480-A353C3DB86A4} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x06D00000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ForwardSubNormalizeOnStore + extends [System.Runtime]System.Object +{ + .method private hidebysig static int32 + Problem(int32 a) cil managed noinlining + { + // Code size 4 (0x4) + .maxstack 1 + .locals init (int16 V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ret + } // end of method ForwardSubTests::Problem + + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 11 (0xb) + .maxstack 8 + IL_0000: ldc.i4 0xf0064 + IL_0005: call int32 ForwardSubTests::Problem(int32) + IL_000a: ret + } // end of method ForwardSubTests::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [System.Runtime]System.Object::.ctor() + IL_0006: ret + } // end of method ForwardSubTests::.ctor + +} // end of class ForwardSubTests + +.class private auto ansi store_ProcessedByFody + extends [System.Runtime]System.Object +{ + .field static assembly literal string FodyVersion = "6.6.0.0" + .field static assembly literal string InlineIL = "1.7.1.0" +} // end of class store_ProcessedByFody + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file normalizeOnStore.res diff --git a/src/tests/JIT/opt/ForwardSub/normalizeOnStore.ilproj b/src/tests/JIT/opt/ForwardSub/normalizeOnStore.ilproj new file mode 100644 index 00000000000000..477cccfe1def03 --- /dev/null +++ b/src/tests/JIT/opt/ForwardSub/normalizeOnStore.ilproj @@ -0,0 +1,13 @@ + + + Exe + 1 + + + None + True + + + + + diff --git a/src/tests/Loader/classloader/RefFields/InvalidCSharp.il b/src/tests/Loader/classloader/RefFields/InvalidCSharp.il index 7fc74717dd1029..768f603f22d55c 100644 --- a/src/tests/Loader/classloader/RefFields/InvalidCSharp.il +++ b/src/tests/Loader/classloader/RefFields/InvalidCSharp.il @@ -5,26 +5,46 @@ .assembly InvalidCSharp { } -.class public auto ansi sealed beforefieldinit InvalidCSharp.InvalidStructWithRefField +.class public sequential ansi sealed beforefieldinit InvalidCSharp.InvalidStructWithRefField extends [System.Runtime]System.ValueType { // Type requires IsByRefLikeAttribute to be valid. - .field public string& invalid + .field public string& Invalid +} + +.class public explicit ansi sealed beforefieldinit InvalidCSharp.InvalidRefFieldAlignment + extends [System.Runtime]System.ValueType +{ + .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( + 01 00 00 00 + ) + .field [0] public int16 Field + .field [2] public int32& Invalid +} + +.class public explicit ansi sealed beforefieldinit InvalidCSharp.InvalidObjectRefRefFieldOverlap + extends [System.Runtime]System.ValueType +{ + .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( + 01 00 00 00 + ) + .field [0] public object Field + .field [0] public int32& Invalid } // This is invalid metadata and is unable to be loaded. // - [field sig] (0x80131815 (VER_E_FIELD_SIG)) // -// .class public auto ansi sealed beforefieldinit InvalidCSharp.InvalidStructWithStaticRefField +// .class public sequential ansi sealed beforefieldinit InvalidCSharp.InvalidStructWithStaticRefField // extends [System.Runtime]System.ValueType // { // .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( // 01 00 00 00 // ) -// .field public static string& invalid +// .field public static string& Invalid // } -.class public auto ansi sealed beforefieldinit InvalidCSharp.WithRefField +.class public sequential ansi sealed beforefieldinit InvalidCSharp.WithRefField extends [System.Runtime]System.ValueType { .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( @@ -57,7 +77,7 @@ } } -.class public auto ansi sealed beforefieldinit InvalidCSharp.WithRefStructField +.class public sequential ansi sealed beforefieldinit InvalidCSharp.WithRefStructField extends [System.Runtime]System.ValueType { .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( @@ -91,7 +111,7 @@ } } -.class public auto ansi sealed beforefieldinit InvalidCSharp.WithTypedReferenceField`1 +.class public sequential ansi sealed beforefieldinit InvalidCSharp.WithTypedReferenceField`1 extends [System.Runtime]System.ValueType { .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( @@ -101,11 +121,11 @@ .method public hidebysig specialname rtspecialname instance void .ctor ( - !T + !T& ) cil managed { ldarg.0 - ldarga.s 1 + ldarg.1 mkrefany !T stfld typedref valuetype InvalidCSharp.WithTypedReferenceField`1::Field ret @@ -120,4 +140,18 @@ call class [System.Runtime]System.Type [System.Runtime]System.Type::GetTypeFromHandle(valuetype [System.Runtime]System.RuntimeTypeHandle ) ret } + + .method public hidebysig + instance bool ConfirmFieldInstance ( + !T + ) cil managed + { + ldarg.0 + ldfld typedref valuetype InvalidCSharp.WithTypedReferenceField`1::Field + refanyval !T + ldind.ref + ldarg.1 + ceq + ret + } } diff --git a/src/tests/Loader/classloader/RefFields/Validate.cs b/src/tests/Loader/classloader/RefFields/Validate.cs index bffcd53de2f00a..b286d51f2f6aae 100644 --- a/src/tests/Loader/classloader/RefFields/Validate.cs +++ b/src/tests/Loader/classloader/RefFields/Validate.cs @@ -3,6 +3,7 @@ using System; using System.IO; +using System.Runtime.CompilerServices; using InvalidCSharp; using Xunit; @@ -14,6 +15,8 @@ public static void Validate_Invalid_RefField_Fails() { Console.WriteLine($"{nameof(Validate_Invalid_RefField_Fails)}..."); Assert.Throws(() => { var t = typeof(InvalidStructWithRefField); }); + Assert.Throws(() => { var t = typeof(InvalidRefFieldAlignment); }); + Assert.Throws(() => { var t = typeof(InvalidObjectRefRefFieldOverlap); }); } [Fact] @@ -23,17 +26,43 @@ public static void Validate_RefStructWithRefField_Load() var t = typeof(WithRefField); } + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Create_RefField_Worker(string str, int depth) + { + if (depth == 5) + { + return; + } + + WithRefField s = new(ref str); + string newStr = new(str); + + Create_RefField_Worker(str + $" {depth}", depth + 1); + Assert.False(s.ConfirmFieldInstance(newStr)); + Assert.True(s.ConfirmFieldInstance(str)); + } + [Fact] public static void Validate_Create_RefField() { var str = nameof(Validate_Create_RefField); Console.WriteLine($"{str}..."); + Create_RefField_Worker(str, 1); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Create_RefStructField_Worker(string str, int depth) + { + if (depth == 5) + { + return; + } WithRefField s = new(ref str); - Assert.True(s.ConfirmFieldInstance(str)); + WithRefStructField t = new(ref s); - string newStr = new(str); - Assert.False(s.ConfirmFieldInstance(newStr)); + Create_RefStructField_Worker(str + $" {depth}", depth + 1); + Assert.True(t.ConfirmFieldInstance(ref s)); } [Fact] @@ -41,10 +70,22 @@ public static void Validate_Create_RefStructField() { var str = nameof(Validate_Create_RefStructField); Console.WriteLine($"{str}..."); + Create_RefStructField_Worker(str, 1); + } - WithRefField s = new(ref str); - WithRefStructField t = new(ref s); - Assert.True(t.ConfirmFieldInstance(ref s)); + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Create_TypedReferenceRefField_Worker(Validate v, int depth) + { + if (depth == 5) + { + return; + } + + WithTypedReferenceField s = new(ref v); + + Create_TypedReferenceRefField_Worker(v, depth + 1); + Assert.Equal(typeof(Validate), s.GetFieldType()); + Assert.True(s.ConfirmFieldInstance(v)); } [Fact] @@ -53,7 +94,6 @@ public static void Validate_Create_TypedReferenceRefField() Console.WriteLine($"{nameof(Validate_Create_TypedReferenceRefField)}..."); Validate v = new(); - WithTypedReferenceField s = new(v); - Assert.Equal(typeof(Validate), s.GetFieldType()); + Create_TypedReferenceRefField_Worker(v, 1); } } \ No newline at end of file diff --git a/src/tests/issues.targets b/src/tests/issues.targets index d14ab8edbdbc12..49579ecd10dbc7 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -195,6 +195,10 @@ Allocates large contiguous array that is not consistently available on 32-bit platforms + + + https://github.com/dotnet/runtime/issues/60154 + @@ -235,6 +239,17 @@ https://github.com/dotnet/runtime/issues/60036 + + + https://github.com/dotnet/runtime/issues/60154 + + + https://github.com/dotnet/runtime/issues/60154 + + + + https://github.com/dotnet/runtime/issues/60154 + @@ -252,6 +267,17 @@ https://github.com/dotnet/runtime/issues/57458 + + + https://github.com/dotnet/runtime/issues/60154 + + + https://github.com/dotnet/runtime/issues/60154 + + + + https://github.com/dotnet/runtime/issues/60154 + @@ -286,6 +312,17 @@ https://github.com/dotnet/runtime/issues/57458 + + + https://github.com/dotnet/runtime/issues/60154 + + + https://github.com/dotnet/runtime/issues/60154 + + + + https://github.com/dotnet/runtime/issues/60154 + @@ -568,6 +605,17 @@ Needs Triage + + + https://github.com/dotnet/runtime/issues/60154 + + + https://github.com/dotnet/runtime/issues/60154 + + + + https://github.com/dotnet/runtime/issues/60154 + @@ -893,12 +941,6 @@ https://github.com/dotnet/runtimelab/issues/155: AssemblyLoadContext.LoadFromAssemblyPath - - https://github.com/dotnet/runtimelab/issues/160 - - - https://github.com/dotnet/runtimelab/issues/160 - https://github.com/dotnet/runtimelab/issues/155: C++/CLI @@ -945,7 +987,7 @@ https://github.com/dotnet/runtimelab/issues/173 - https://github.com/dotnet/runtimelab/issues/160 + Specific to CoreCLR: Built-in COM Interop https://github.com/dotnet/runtimelab/issues/175 @@ -2860,9 +2902,6 @@ needs triage - - https://github.com/dotnet/runtime/issues/62334 - diff --git a/src/tests/profiler/multiple/multiple.cs b/src/tests/profiler/multiple/multiple.cs index 9de72d96198054..aa0388fa0eb293 100644 --- a/src/tests/profiler/multiple/multiple.cs +++ b/src/tests/profiler/multiple/multiple.cs @@ -16,7 +16,7 @@ class MultiplyLoaded [DllImport("Profiler")] private static extern void PassCallbackToProfiler(ProfilerCallback callback); - public static int RunTest(String[] args) + public static int RunTest(String[] args) { ManualResetEvent _profilerDone = new ManualResetEvent(false); PassCallbackToProfiler(() => _profilerDone.Set()); @@ -45,6 +45,11 @@ public static int RunTest(String[] args) public static int Main(string[] args) { + // failing on MacOs 12 https://github.com/dotnet/runtime/issues/64765 + if (OperatingSystem.IsMacOS()) + { + return 100; + } if (args.Length > 0 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase)) { return RunTest(args); diff --git a/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs b/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs index d319b4c9905378..84d1c0dbab2bf6 100644 --- a/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs +++ b/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.Collections.Generic; using System.Reflection; +using System.Runtime.InteropServices; using Microsoft.Diagnostics.Tools.RuntimeClient; using Tracing.Tests.Common; using System.Threading; @@ -305,6 +306,133 @@ public static async Task TEST_DisabledCommandsError() return fSuccess; } + public static async Task TEST_ProcessInfoBeforeAndAfterSuspension() + { + // This test only applies to platforms where the PAL is used + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return true; + + // This test only applies to CoreCLR (this checks if we're running on Mono) + if (Type.GetType("Mono.RuntimeStructs") != null) + return true; + + bool fSuccess = true; + string serverName = ReverseServer.MakeServerAddress(); + Logger.logger.Log($"Server name is '{serverName}'"); + var server = new ReverseServer(serverName); + using var memoryStream1 = new MemoryStream(); + using var memoryStream2 = new MemoryStream(); + using var memoryStream3 = new MemoryStream(); + Task subprocessTask = Utils.RunSubprocess( + currentAssembly: Assembly.GetExecutingAssembly(), + environment: new Dictionary { { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, + duringExecution: async (pid) => + { + Process currentProcess = Process.GetCurrentProcess(); + + Stream stream = await server.AcceptAsync(); + IpcAdvertise advertise = IpcAdvertise.Parse(stream); + Logger.logger.Log(advertise.ToString()); + + Logger.logger.Log($"Get ProcessInfo while process is suspended"); + // 0x04 = ProcessCommandSet, 0x04 = ProcessInfo2 + var message = new IpcMessage(0x04, 0x04); + Logger.logger.Log($"Sent: {message.ToString()}"); + IpcMessage response = IpcClient.SendMessage(stream, message); + Logger.logger.Log($"received: {response.ToString()}"); + + ProcessInfo2 pi2Before = ProcessInfo2.TryParse(response.Payload); + Utils.Assert(pi2Before.Commandline.Equals(currentProcess.MainModule.FileName), $"Before resuming, the commandline should be the mock value of the host executable path '{currentProcess.MainModule.FileName}'. Observed: '{pi2Before.Commandline}'"); + + // recycle + stream = await server.AcceptAsync(); + advertise = IpcAdvertise.Parse(stream); + Logger.logger.Log(advertise.ToString()); + + // Start EP session to know when runtime is resumed + var config = new SessionConfiguration( + circularBufferSizeMB: 1000, + format: EventPipeSerializationFormat.NetTrace, + providers: new List { + new Provider("Microsoft-Windows-DotNETRuntimePrivate", 0x80000000, EventLevel.Verbose), + new Provider("Microsoft-DotNETCore-SampleProfiler") + }); + Logger.logger.Log("Starting EventPipeSession over standard connection"); + using Stream eventStream = EventPipeClient.CollectTracing(pid, config, out var sessionId); + Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); + + TaskCompletionSource runtimeResumed = new(false, TaskCreationOptions.RunContinuationsAsynchronously); + + var eventPipeTask = Task.Run(() => + { + Logger.logger.Log("Creating source"); + using var source = new EventPipeEventSource(eventStream); + var parser = new ClrPrivateTraceEventParser(source); + parser.StartupEEStartupStart += (_) => runtimeResumed.SetResult(true); + source.Process(); + Logger.logger.Log("stopping processing"); + }); + + Logger.logger.Log($"Send ResumeRuntime Diagnostics IPC Command"); + // send ResumeRuntime command (0x04=ProcessCommandSet, 0x01=ResumeRuntime commandid) + message = new IpcMessage(0x04,0x01); + Logger.logger.Log($"Sent: {message.ToString()}"); + response = IpcClient.SendMessage(stream, message); + Logger.logger.Log($"received: {response.ToString()}"); + + // recycle + stream = await server.AcceptAsync(); + advertise = IpcAdvertise.Parse(stream); + Logger.logger.Log(advertise.ToString()); + + // wait a little bit to make sure the runtime of the target is fully up, i.e., g_EEStarted == true + // on resource constrained CI machines this may not be instantaneous + Logger.logger.Log($"awaiting resume"); + await Utils.WaitTillTimeout(runtimeResumed.Task, TimeSpan.FromSeconds(10)); + Logger.logger.Log($"resumed"); + + // await Task.Delay(TimeSpan.FromSeconds(1)); + Logger.logger.Log("Stopping EventPipeSession over standard connection"); + EventPipeClient.StopTracing(pid, sessionId); + Logger.logger.Log($"Await reader task"); + await eventPipeTask; + Logger.logger.Log("Stopped EventPipeSession over standard connection"); + + ProcessInfo2 pi2After = default; + + // The timing is not exact. There is a small window after resuming where the mock + // value is still present. Retry several times to catch it. + var retryTask = Task.Run(async () => + { + int i = 0; + do { + Logger.logger.Log($"Get ProcessInfo after resumption: attempt {i++}"); + // 0x04 = ProcessCommandSet, 0x04 = ProcessInfo2 + message = new IpcMessage(0x04, 0x04); + Logger.logger.Log($"Sent: {message.ToString()}"); + response = IpcClient.SendMessage(stream, message); + Logger.logger.Log($"received: {response.ToString()}"); + + pi2After = ProcessInfo2.TryParse(response.Payload); + + // recycle + stream = await server.AcceptAsync(); + advertise = IpcAdvertise.Parse(stream); + Logger.logger.Log(advertise.ToString()); + } while (pi2After.Commandline.Equals(pi2Before.Commandline)); + }); + + await Utils.WaitTillTimeout(retryTask, TimeSpan.FromSeconds(10)); + + Utils.Assert(!pi2After.Commandline.Equals(pi2Before.Commandline), $"After resuming, the commandline should be the correct value. Observed: Before='{pi2Before.Commandline}' After='{pi2After.Commandline}'"); + } + ); + + fSuccess &= await subprocessTask; + + return fSuccess; + } + public static async Task Main(string[] args) { if (args.Length >= 1)