-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path07_BuilderPattern.ps1
More file actions
104 lines (90 loc) · 3.29 KB
/
Copy path07_BuilderPattern.ps1
File metadata and controls
104 lines (90 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<#
.SYNOPSIS
OOP Reference: Builder Pattern
.DESCRIPTION
Topic: Fluent multi-step object construction
Category: Creational
Agent Task: Add a WithEcdhKeyExchange() method to the builder that sets Algorithm
to 'ECDH-P256' and KeyBits to 256. Add validation that ECDH requires
KeyBits == 256. Add Pester tests covering the fluent chain and validation failures.
Done Conditions:
- Fluent chain builds a valid CryptoConfig
- Build() throws on invalid config (iterations < 10000, bad key size)
- Pester tests pass: Invoke-Pester -Output Detailed
Non-Scope:
- Do not implement actual ECDH crypto — config only
#>
class CryptoConfig {
[string]$Algorithm = 'AES-256-GCM'
[int]$KeyBits = 256
[int]$NonceBits = 96
[int]$TagBits = 128
[bool]$AuditEnabled = $false
[int]$MaxOpsPerMinute = 1000
[string]$KeyDerivation = 'PBKDF2-SHA256'
[int]$KdfIterations = 100000
[byte[]]$StaticKey = $null
[string]$Version = '1'
[string] ToString() {
return "[$($this.Algorithm)] key=$($this.KeyBits)b kdf=$($this.KeyDerivation) iter=$($this.KdfIterations) audit=$($this.AuditEnabled)"
}
}
class CryptoConfigBuilder {
hidden [CryptoConfig]$_config
CryptoConfigBuilder() { $this._config = [CryptoConfig]::new() }
[CryptoConfigBuilder] UseAesGcm([int]$keyBits = 256) {
$this._config.Algorithm = 'AES-256-GCM'
$this._config.KeyBits = $keyBits
return $this
}
[CryptoConfigBuilder] WithAudit() {
$this._config.AuditEnabled = $true
return $this
}
[CryptoConfigBuilder] WithRateLimit([int]$opsPerMinute) {
$this._config.MaxOpsPerMinute = $opsPerMinute
return $this
}
[CryptoConfigBuilder] WithPbkdf2([int]$iterations) {
$this._config.KeyDerivation = 'PBKDF2-SHA256'
$this._config.KdfIterations = $iterations
return $this
}
[CryptoConfigBuilder] WithStaticKey([byte[]]$key) {
if ($key.Length -notin @(16, 24, 32)) {
throw [System.ArgumentException]'Key must be 128/192/256-bit'
}
$this._config.StaticKey = $key
return $this
}
[CryptoConfigBuilder] WithEcdhKeyExchange() {
$this._config.Algorithm = 'ECDH-P256'
$this._config.KeyBits = 256
return $this
}
[CryptoConfig] Build() {
if ($this._config.KdfIterations -lt 10000) {
throw [System.InvalidOperationException]'PBKDF2 iterations too low (min 10000)'
}
# Validate ECDH requires 256-bit keys
if ($this._config.Algorithm -eq 'ECDH-P256' -and $this._config.KeyBits -ne 256) {
throw [System.InvalidOperationException]'ECDH-P256 requires 256-bit keys'
}
if ($this._config.KeyBits -notin @(128, 192, 256)) {
throw [System.InvalidOperationException]"Invalid key size: $($this._config.KeyBits)"
}
return $this._config
}
}
# Usage:
# $config = [CryptoConfigBuilder]::new()
# .UseAesGcm(256)
# .WithAudit()
# .WithRateLimit(500)
# .WithPbkdf2(200000)
# .Build()
#
# $ecdhConfig = [CryptoConfigBuilder]::new()
# .WithEcdhKeyExchange()
# .WithAudit()
# .Build()