# バッチ設計書 42-sign-with-dac-certificate.ps1

## 概要

本ドキュメントは、DAC（Data Access Component）証明書を使用してファイルにコード署名を行うPowerShellスクリプト `eng/native/sign-with-dac-certificate.ps1` の設計を記述します。このスクリプトは、.NET Runtimeのデバッグ関連コンポーネントのセキュリティ署名を自動化します。

### 本バッチの処理概要

このバッチでは、ESRPクライアントを使用して指定されたファイルに.NET DAC証明書でコード署名を行い、署名の正当性を検証します。

**業務上の目的・背景**：.NET RuntimeにはDAC（Data Access Component）と呼ばれるデバッグ用コンポーネントが含まれています。これらのコンポーネントはデバッガーがプロセスメモリにアクセスするため、特別な信頼チェーンに基づいた署名が必要です。不正なDACコンポーネントはセキュリティリスクとなるため、Microsoft社の正式な証明書による署名が義務付けられています。

**バッチの実行タイミング**：リリースビルド時、DACコンポーネント（mscordaccore.dll等）の生成後に実行されます。CI/CDパイプラインの署名ステップで呼び出されます。

**主要な処理内容**：
1. ESRPクライアントに渡す入力JSONを生成
2. ESRPクライアントを実行してファイルに署名
3. 各ファイルの署名証明書を検証
4. 証明書の発行者とサブジェクトを確認
5. EKU（Enhanced Key Usage）の正当性を検証

**前後の処理との関連**：ネイティブビルドでDACコンポーネントが生成された後に実行されます。署名後のファイルはNuGetパッケージに含められ、配布されます。

**影響範囲**：DACコンポーネントの配布と使用に直接影響します。署名が失敗すると、デバッグ機能が正しく動作しない可能性があります。

## バッチ種別

セキュリティ / コード署名

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | リリースビルド時 |
| 実行時刻 | CI/CDパイプライン実行時 |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | リリースビルドパイプラインからの呼び出し |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| ESRPクライアント | ESRPクライアント実行ファイルへのパスが必要 |
| 署名設定ファイル | auth.json、config.json、policy.json、input.template.jsonが必要 |
| Azure DevOps環境 | ESRPサービスへのアクセス権限が必要 |
| 署名対象ファイル | 署名するファイルが存在すること |

### 実行可否判定

ESRPクライアントパスが無効、または署名対象ファイルが存在しない場合は失敗します。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| esrpClient | string | Yes | なし | ESRPクライアント実行ファイルのパス |
| filesToSign | string[] | Yes | なし | 署名対象ファイルのパス（可変長引数） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| signing/input.template.json | JSON | 署名バッチ設定のテンプレート |
| signing/auth.json | JSON | ESRP認証設定 |
| signing/config.json | JSON | ESRP構成設定 |
| signing/policy.json | JSON | 署名ポリシー設定 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 署名対象ファイル | バイナリ | 署名が付与されたファイル（インプレース更新） |
| ログファイル | JSON | artifacts/log/Release/signing-{GUID}.json.log |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | signing-{GUID}.json.log |
| 出力先 | artifacts/log/Release/ |
| 文字コード | UTF-8 |
| 形式 | JSON |

## 処理フロー

### 処理シーケンス

```
1. 入力JSONの構築
   └─ input.template.jsonを読み込み
   └─ SignBatchesにファイルパスを設定
   └─ 一時ファイルとしてJSON出力
2. ESRPクライアントの実行
   └─ auth.json、config.json、policy.jsonを指定
   └─ 入力JSON、出力ログパスを指定
   └─ signコマンドを実行
3. 署名検証ループ（各ファイル）
   └─ Get-AuthenticodeSignatureで署名情報取得
   └─ 署名の存在確認
   └─ 証明書サブジェクトの検証
   └─ 証明書発行者の検証
   └─ EKU（1.3.6.1.4.1.311.84.4.1）の検証
4. 検証結果の出力
   └─ 成功時: "ファイル名 is correctly signed."
   └─ 失敗時: 例外をスロー
```

### フローチャート

```mermaid
flowchart TD
    A[スクリプト開始] --> B[input.template.json読み込み]
    B --> C[ファイルリストをJSONに設定]
    C --> D[一時JSONファイル生成]
    D --> E[出力ログパス生成]
    E --> F[ESRPクライアント実行]
    F --> G[署名検証ループ開始]
    G --> H{ファイルあり?}
    H -->|Yes| I[Get-AuthenticodeSignature]
    I --> J{署名存在?}
    J -->|No| K[例外: 署名なし]
    J -->|Yes| L{サブジェクト正当?}
    L -->|No| M[例外: 信頼チェーン不正]
    L -->|Yes| N{発行者正当?}
    N -->|No| M
    N -->|Yes| O{EKU正当?}
    O -->|No| P[例外: EKU不正]
    O -->|Yes| Q[署名成功メッセージ]
    Q --> H
    H -->|No| R[正常終了]
    K --> S[異常終了]
    M --> S
    P --> S
```

## データベース操作仕様

本スクリプトはデータベース操作を行いません。

### 操作別データベース影響一覧

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Exception | 署名なし | ファイルに署名が含まれていない | ESRPクライアントの実行ログを確認 |
| Exception | 信頼チェーン不正 | サブジェクトまたは発行者が期待値と異なる | 署名設定とポリシーを確認 |
| Exception | EKU不正 | 期待されるEKUが含まれていない | 署名ポリシーを確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（ESRPクライアント内部でリトライ） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. ESRPクライアントのログを確認してエラー原因を特定
2. 認証情報（auth.json）の有効性を確認
3. 署名ポリシー（policy.json）が正しく設定されているか確認
4. ネットワーク接続とESRPサービスの可用性を確認

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイル操作） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1-10ファイル |
| 目標処理時間 | ファイルあたり30秒以内 |
| メモリ使用量上限 | PowerShell標準使用量内 |

## 排他制御

ESRPクライアントが内部で排他制御を行います。同一ファイルへの同時署名は避けてください。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 情報ログ | 署名開始時 | "Signing files with DAC certificate" |
| 情報ログ | 署名開始時 | "Logging output to {出力パス}" |
| 情報ログ | 検証成功時 | "{ファイル名} is correctly signed." |
| エラーログ | 検証失敗時 | 例外メッセージ |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 署名失敗 | 1件以上 | CIパイプライン通知 |
| 処理時間 | 5分超過 | CIパイプライン通知 |

## 備考

- 証明書サブジェクト: `CN=.NET DAC, O=Microsoft Corporation, L=Redmond, S=Washington, C=US`
- 証明書発行者: `CN=Microsoft Windows Code Signing PCA 2024, O=Microsoft Corporation, C=US`
- 必要なEKU OID: `1.3.6.1.4.1.311.84.4.1`
- このスクリプトはMicrosoft社内のリリースビルド環境でのみ使用可能です
- ESRPクライアントとの通信にはAzure DevOpsの認証が必要です
