diff --git a/.pipelines/templates/mac-package-build.yml b/.pipelines/templates/mac-package-build.yml index 6585773c743..154cb6c0257 100644 --- a/.pipelines/templates/mac-package-build.yml +++ b/.pipelines/templates/mac-package-build.yml @@ -76,6 +76,14 @@ jobs: # Diagnostics is not critical it passes every time it runs continueOnError: true + - pwsh: | + $signedDir = "$(Pipeline.Workspace)/CoOrdinatedBuildPipeline/drop_macos_sign_${{ parameters.buildArchitecture }}/Signed-${{ parameters.buildArchitecture }}" + Get-ChildItem $signedDir -Recurse -Include 'pwsh', '*.dylib' | ForEach-Object { + codesign --verify --deep --strict --verbose=4 $_.FullName + if ($LASTEXITCODE -ne 0) { throw "codesign verification failed for $($_.FullName)" } + } + displayName: 'Verify Apple codesign on signed binaries' + - pwsh: | # Add -SkipReleaseChecks as a mitigation to unblock release. # macos-10.15 does not allow creating a folder under root. Hence, moving the folder. @@ -158,7 +166,12 @@ jobs: Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$file" } + $packageInfo = Get-MacOSPackageIdentifierInfo -Version '$(Version)' -LTS:$LTS + Write-Verbose -Verbose "BundleId: $($packageInfo.PackageIdentifier)" + Write-Host "##vso[task.setvariable variable=BundleId;isOutput=true]$($packageInfo.PackageIdentifier)" + displayName: 'Package ${{ parameters.buildArchitecture}}' + name: packageStep env: __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) @@ -178,7 +191,8 @@ jobs: value: $(Build.SourcesDirectory)/PowerShell/.config/suppress.json - name: BuildArch value: ${{ parameters.buildArchitecture }} - - group: mscodehub-macos-package-signing + - name: BundleId + value: $[ dependencies.package_macOS_${{ parameters.buildArchitecture }}.outputs['packageStep.BundleId'] ] steps: - download: current @@ -216,32 +230,59 @@ jobs: inline_operation: | [ { - "KeyCode": "$(KeyCode)", + "KeyCode": "CP-401337-Apple", "OperationCode": "MacAppDeveloperSign", "ToolName": "sign", "ToolVersion": "1.0", "Parameters": { - "Hardening": "Enable", - "OpusInfo": "http://microsoft.com" + "Hardening": "--options=runtime" } } ] + - task: onebranch.pipeline.signing@1 + displayName: 'OneBranch Notarize Package' + inputs: + command: 'sign' + files_to_sign: '**/*-osx-*.zip' + search_root: '$(Pipeline.Workspace)' + inline_operation: | + [ + { + "KeyCode": "CP-401337-Apple", + "OperationCode": "MacAppNotarize", + "ToolName": "sign", + "ToolVersion": "1.0", + "Parameters": { + "BundleId": "$(BundleId)" + } + } + ] + timeoutInMinutes: 120 + - pwsh: | $signedPkg = Get-ChildItem -Path $(Pipeline.Workspace) -Filter "*osx*.zip" -File + if (-not (Test-Path $(ob_outputDirectory))) { + $null = New-Item -Path $(ob_outputDirectory) -ItemType Directory + } + + $expandDir = "$(Pipeline.Workspace)/pkgExpand" + $null = New-Item -Path $expandDir -ItemType Directory -Force + $signedPkg | ForEach-Object { Write-Verbose -Verbose "Signed package zip: $_" + Expand-Archive -Path $_ -DestinationPath $expandDir -Verbose + } - if (-not (Test-Path $_)) { - throw "Package not found: $_" - } - - if (-not (Test-Path $(ob_outputDirectory))) { - $null = New-Item -Path $(ob_outputDirectory) -ItemType Directory - } + # ESRP's signing pipeline nests the PKG inside a '.zip.unzipped' subfolder + $pkgFile = Get-ChildItem -Path $expandDir -Filter '*.pkg' -Recurse -File + if (-not $pkgFile) { + throw "Package not found in: $signedPkg" + } - Expand-Archive -Path $_ -DestinationPath $(ob_outputDirectory) -Verbose + $pkgFile | ForEach-Object { + Move-Item -Path $_ -Destination $(ob_outputDirectory) -Verbose } Write-Verbose -Verbose "Expanded pkg file:" diff --git a/.pipelines/templates/mac.yml b/.pipelines/templates/mac.yml index 1699207c657..b22149d5e46 100644 --- a/.pipelines/templates/mac.yml +++ b/.pipelines/templates/mac.yml @@ -69,6 +69,14 @@ jobs: $psOptPath = "$(OB_OUTPUTDIRECTORY)/psoptions.json" Save-PSOptions -PSOptionsPath $psOptPath + $entitlements = "$(PowerShellRoot)/assets/macos-entitlements.plist" + $pwshBin = "$(OB_OUTPUTDIRECTORY)/pwsh" + Write-Verbose -Verbose "Applying entitlements to $pwshBin" + codesign --sign - --force --options runtime --entitlements $entitlements $pwshBin + if ($LASTEXITCODE -ne 0) { + throw "codesign failed with exit code $LASTEXITCODE" + } + # Since we are using custom pool for macOS, we need to use artifact.upload to publish the artifacts Write-Host "##vso[artifact.upload containerfolder=$artifactName;artifactname=$artifactName]$(OB_OUTPUTDIRECTORY)" @@ -144,4 +152,36 @@ jobs: binPath: $(DropRootPath) OfficialBuild: $(ps_official_build) + # Apple-sign the Mach-O binaries inside the signed output. + - pwsh: | + $signedDir = "$(ob_outputDirectory)/Signed-$(Runtime)" + $zipFile = "$(Pipeline.Workspace)/macho-$(BuildArchitecture).zip" + Compress-Archive -Path "$signedDir/*" -DestinationPath $zipFile -Force + displayName: Compress signed folder for Apple signing + + - task: onebranch.pipeline.signing@1 + displayName: Apple CodeSign Mach-O binaries + inputs: + command: 'sign' + files_to_sign: 'macho-$(BuildArchitecture).zip' + search_root: '$(Pipeline.Workspace)' + inline_operation: | + [ + { + "KeyCode": "CP-401337-Apple", + "OperationCode": "MacAppDeveloperSign", + "ToolName": "sign", + "ToolVersion": "1.0", + "Parameters": { + "Hardening": "--options=runtime" + } + } + ] + + - pwsh: | + $signedDir = "$(ob_outputDirectory)/Signed-$(Runtime)" + $zipFile = "$(Pipeline.Workspace)/macho-$(BuildArchitecture).zip" + Expand-Archive -Path $zipFile -DestinationPath $signedDir -Force -Verbose + displayName: Expand Apple-signed Mach-O binaries into signed output + - template: /.pipelines/templates/step/finalize.yml@self diff --git a/assets/macos-entitlements.plist b/assets/macos-entitlements.plist new file mode 100644 index 00000000000..9d534f4f4bf --- /dev/null +++ b/assets/macos-entitlements.plist @@ -0,0 +1,14 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.cs.disable-library-validation + + + diff --git a/tools/packaging/packaging.psd1 b/tools/packaging/packaging.psd1 index 0053428a481..e5b7fb84dfc 100644 --- a/tools/packaging/packaging.psd1 +++ b/tools/packaging/packaging.psd1 @@ -26,6 +26,7 @@ 'Test-PackageManifest' 'Update-PSSignedBuildFolder' 'Test-Bom' + 'Get-MacOSPackageIdentifierInfo' ) RootModule = "packaging.psm1" RequiredModules = @("build")