# 機能設計書 604-New-DbaComputerCertificateSigningRequest

## 概要

本ドキュメントは、SQL ServerインスタンスのSSL/TLS暗号化のための証明書署名要求（CSR）を生成する`New-DbaComputerCertificateSigningRequest`機能の設計書である。

### 本機能の処理概要

`New-DbaComputerCertificateSigningRequest`は、証明機関（CA）に送信してSSL/TLS証明書を取得するための証明書署名要求（CSR）を生成する機能である。証明書要求の手動作成プロセスを排除し、SQL Serverの暗号化要件に適した構成を自動的に生成する。

**業務上の目的・背景**：企業環境では、内部CAまたは外部CA（DigiCert、GlobalSign等）から署名された証明書を使用することがセキュリティポリシーで要求される場合がある。本機能は、証明書署名要求の作成を自動化し、適切なSubject Alternative Name（SAN）を含む構成ファイルとCSRファイルを生成する。これにより、管理者はCSRファイルをCAに送信するだけで、SQL Serverに適した証明書を取得できる。

**機能の利用シーン**：
- 外部CA（商用証明機関）から署名された証明書を取得する場合
- 社内CAへの証明書要求の自動化
- SQL Serverフェイルオーバークラスタ用の証明書要求作成
- 複数サーバーへの証明書要求の一括生成

**主要な処理内容**：
1. FQDN解決によるサーバー名の特定
2. Subject Alternative Name（SAN）拡張の生成
3. 証明書要求構成ファイル（.inf）の作成
4. certreq -new コマンドによるCSRファイル生成
5. 構成ファイルとCSRファイルの出力

**関連システム・外部連携**：Windows証明書サービス、PowerShellリモーティング

**権限による制御**：管理者権限（RunAs Admin）が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | なし | - | CLIベースの機能のため関連画面なし |

## 機能種別

ファイル出力 / 証明書要求生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstance[] | No | 証明書を作成する対象コンピュータ名（デフォルト: localhost） | なし |
| Credential | PSCredential | No | リモートコンピュータ接続用の代替資格情報 | なし |
| ClusterInstanceName | String | No | SQL Serverフェイルオーバークラスタの仮想クラスタ名 | なし |
| Path | String | No | CSRファイルの出力ディレクトリ（デフォルト: dbatools エクスポートパス） | なし |
| FriendlyName | String | No | 証明書のフレンドリ名（デフォルト: "SQL Server"） | なし |
| KeyLength | Int | No | RSAキーサイズ（ビット）（デフォルト: 1024） | なし |
| Dns | String[] | No | 証明書のSANに含める追加DNS名 | なし |
| EnableException | Switch | No | 例外処理の有効化フラグ | なし |

### 入力データソース

- 環境変数（$env:USERDNSDOMAIN）
- dbatools設定（Path.DbatoolsExport）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Name | String | ファイル名（request.inf または <fqdn>.csr） |
| FullName | String | 完全なファイルパス |
| DirectoryName | String | ファイルが格納されているディレクトリ |
| Length | Int64 | ファイルサイズ（バイト） |
| LastWriteTime | DateTime | ファイルの最終更新日時 |
| CreationTime | DateTime | ファイルの作成日時 |
| Extension | String | ファイル拡張子（.inf または .csr） |

### 出力先

- ファイルシステム（指定されたPath内にコンピュータごとのサブディレクトリ）
- PowerShellパイプライン（System.IO.FileInfo オブジェクト）

## 処理フロー

### 処理シーケンス

```
1. 前処理（beginブロック）
   ├─ OS言語チェック（英語のみサポート）
   ├─ GetHexLength関数の定義
   └─ Get-SanExt関数の定義
2. 各ComputerNameに対して処理（processブロック）
   ├─ 管理者権限チェック
   ├─ FQDN解決（Resolve-DbaNetworkName）
   ├─ 出力ディレクトリ作成/クリア
   ├─ SAN拡張の生成
   ├─ 証明書要求構成ファイル（.inf）の作成
   ├─ certreq -new でCSRファイルを生成
   └─ 生成されたファイル情報を出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{英語OSロケール?}
    B -->|No| C[エラー終了]
    B -->|Yes| D[ComputerNameループ開始]
    D --> E{管理者権限?}
    E -->|No| F[エラー出力]
    E -->|Yes| G{ClusterInstanceName指定?}
    G -->|Yes| H[クラスタ名をFQDNとして使用]
    G -->|No| I[Resolve-DbaNetworkNameでFQDN解決]
    H --> J[出力ディレクトリ作成/クリア]
    I --> J
    J --> K[SAN拡張生成 Get-SanExt]
    K --> L[証明書要求構成ファイル .inf 作成]
    L --> M[certreq -new 実行]
    M --> N[request.inf と <fqdn>.csr を出力]
    N --> O{次のコンピュータ?}
    O -->|Yes| D
    O -->|No| P[終了]
    F --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-604-01 | 英語OSロケール | 英語版OSでのみサポート | 常時 |
| BR-604-02 | 管理者権限要件 | ローカルマシンでの実行には管理者権限が必要 | 常時 |
| BR-604-03 | デフォルトキー長 | 特に指定がなければ1024ビットのRSAキーを使用 | KeyLength未指定時 |
| BR-604-04 | デフォルトフレンドリ名 | 特に指定がなければ「SQL Server」を使用 | FriendlyName未指定時 |
| BR-604-05 | デフォルトDNS | 特に指定がなければショート名とFQDNの両方をSANに含める | Dns未指定時 |
| BR-604-06 | 出力ファイル | 各コンピュータについてrequest.infと<fqdn>.csrの2ファイルを生成 | 常時 |
| BR-604-07 | 既存ファイル削除 | 出力ディレクトリが存在する場合は内容を削除して再利用 | ディレクトリ存在時 |

### 計算ロジック

**SAN拡張（GetHexLength関数とGet-SanExt関数）**：
- DNS名をASN.1 DER形式に変換
- 各文字を16進数に変換し、適切なタグ（0x82）とレングスバイトを付与
- Base64エンコードして証明書要求に組み込み

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | SQLデータベースへのアクセスなし |

### テーブル別操作詳細

本機能はSQLデータベースにアクセスせず、ファイルシステムのみを操作する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 言語エラー | 英語以外のOSロケール | 英語版OSで実行 |
| - | 権限エラー | 管理者権限なし | 管理者として実行 |
| - | 名前解決失敗 | コンピュータ名を解決できない | ネットワーク構成を確認 |
| - | ファイル作成失敗 | 出力ディレクトリへの書き込み権限なし | 権限を確認 |

### リトライ仕様

特になし

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

ファイルシステム操作のためトランザクション制御なし

## パフォーマンス要件

特に規定なし

## セキュリティ考慮事項

- 管理者権限（RunAs Admin）が必要
- CSRには秘密鍵は含まれないため、安全に転送可能
- 秘密鍵はローカル証明書ストアに保存される
- 生成されたCSRファイルの取り扱いに注意（CAに送信後は不要）

## 備考

- 本機能は英語版OSロケールでのみサポートされている
- New-DbaComputerCertificateと類似の処理だが、CSRファイルの生成のみを行う
- デフォルトキー長は1024ビットだが、セキュリティ上2048ビット以上を推奨

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | New-DbaComputerCertificateSigningRequest.ps1 | `public/New-DbaComputerCertificateSigningRequest.ps1` | 64-80行目のコメントで出力（System.IO.FileInfo）の構造を確認 |
| 1-2 | New-DbaComputerCertificateSigningRequest.ps1 | `public/New-DbaComputerCertificateSigningRequest.ps1` | 102-114行目のparamブロックで入力パラメータ定義を確認 |

**読解のコツ**: 本機能はNew-DbaComputerCertificateと多くのコードを共有しているが、CAへの送信やリモート配布は行わずCSRファイルの生成のみを行う点が異なる。

#### Step 2: エントリーポイントとbeginブロックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | New-DbaComputerCertificateSigningRequest.ps1 | `public/New-DbaComputerCertificateSigningRequest.ps1` | 115-171行目のbeginブロックで初期化処理を確認 |

**主要処理フロー**:
1. **116-120行目**: 英語OSロケールチェック
2. **122-131行目**: GetHexLength関数の定義
3. **133-170行目**: Get-SanExt関数の定義（SAN拡張のASN.1エンコード）

#### Step 3: processブロックの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | New-DbaComputerCertificateSigningRequest.ps1 | `public/New-DbaComputerCertificateSigningRequest.ps1` | 173-261行目でCSR生成処理を確認 |

**主要処理フロー**:
- **178-180行目**: 管理者権限チェック
- **184-204行目**: FQDN解決とクラスタ名処理
- **206-216行目**: 出力ディレクトリの作成/クリア
- **218-225行目**: DNS名リストの構築とSAN拡張生成
- **226-252行目**: 証明書要求構成ファイル（.inf）の生成
- **255-258行目**: certreq -new の実行
- **259行目**: 生成されたファイル情報の出力

### プログラム呼び出し階層図

```
New-DbaComputerCertificateSigningRequest
    │
    ├─ [begin]
    │   ├─ Get-DbaCmObject (OSLanguageチェック)
    │   ├─ GetHexLength (内部関数定義)
    │   └─ Get-SanExt (内部関数定義)
    │
    └─ [process]
        │
        ├─ Test-ElevationRequirement
        │      └─ 管理者権限の確認
        │
        ├─ Resolve-DbaNetworkName
        │      └─ FQDN解決
        │
        ├─ Test-Path / New-Item / Remove-Item
        │      └─ 出力ディレクトリ管理
        │
        ├─ Get-SanExt (内部関数)
        │      └─ SAN拡張のASN.1 DER生成
        │
        ├─ Set-Content / Add-Content
        │      └─ 証明書要求構成ファイル作成
        │
        ├─ certreq -new
        │      └─ CSRファイル生成
        │
        └─ Get-ChildItem
               └─ 生成ファイル情報の取得と出力
```

### データフロー図

```
[入力]                      [処理]                              [出力]

ComputerName ───────▶ FQDN解決 ───────────────────▶ 解決済みホスト名
      │                  │
Path ─┼──────────────────┼────────────────────────▶ 出力ディレクトリ
      │                  │
Dns ──┼──────────────────┼─▶ Get-SanExt
      │                  │      │
      │                  │      ▼
      │                  │  SAN拡張（ASN.1）
      │                  │      │
      │                  ▼      ▼
      │          証明書要求構成ファイル生成
      │                  │
      │                  ▼
      │          certreq -new 実行
      │                  │
      │                  ▼
      │          ┌───────┴───────┐
      │          ▼               ▼
      │     request.inf      <fqdn>.csr
      │          │               │
      │          └───────┬───────┘
      │                  ▼
      └─────────▶ System.IO.FileInfo オブジェクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| New-DbaComputerCertificateSigningRequest.ps1 | `public/New-DbaComputerCertificateSigningRequest.ps1` | ソース | メイン機能実装 |
| Resolve-DbaNetworkName.ps1 | `public/Resolve-DbaNetworkName.ps1` | ソース | ホスト名からFQDNへの解決 |
| Test-ElevationRequirement.ps1 | `private/functions/Test-ElevationRequirement.ps1` | ソース | 管理者権限確認 |
| Get-DbaCmObject.ps1 | `private/functions/Get-DbaCmObject.ps1` | ソース | WMIオブジェクト取得（OSLanguageチェック用） |
| Get-DbatoolsConfigValue.ps1 | `private/functions/Get-DbatoolsConfigValue.ps1` | ソース | デフォルトパス取得 |
