keys-for-all/docs/components/KeyValidator.md
2025-07-22 18:27:21 -07:00

370 lines
No EOL
11 KiB
Markdown

# KeyValidator Component
The KeyValidator handles all key validation logic including format checking, checksum verification, and level extraction. It implements the comprehensive validation system from the main architecture.
## Pseudocode
```swift
class KeyValidator {
// Key format: VUUW-XXXX-XXXX-XXXX-LN
private let keyPattern = "^VUUW-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-L[12]$"
private let checksumVerifier = ChecksumVerifier()
private let cache = ValidationCache(capacity: 1000)
struct ValidationResult {
let isValid: Bool
let level: LicenseLevel?
let error: KeyError?
}
// MARK: - Main Validation
func validate(_ key: String) -> ValidationResult {
// Step 1: Format validation
if !isValidFormat(key) {
return ValidationResult(
isValid: false,
level: nil,
error: .invalidFormat
)
}
// Step 2: Extract components
let components = key.split(separator: "-")
let productID = components[0] // "VUUW"
let segment1 = components[1] // 4 chars
let segment2 = components[2] // 4 chars
let segment3 = components[3] // 4 chars
let levelCode = components[4] // "L1" or "L2"
// Step 3: Validate product ID
if productID != "VUUW" {
return ValidationResult(
isValid: false,
level: nil,
error: .wrongProduct
)
}
// Step 4: Extract and validate level
guard let level = parseLicenseLevel(levelCode) else {
return ValidationResult(
isValid: false,
level: nil,
error: .unsupportedLevel
)
}
// Step 5: Verify checksum
let baseKey = [productID, segment1, segment2, segment3].joined(separator: "-")
let isChecksumValid = verifyChecksum(baseKey, expectedLevel: level)
if !isChecksumValid {
return ValidationResult(
isValid: false,
level: level,
error: .checksumMismatch
)
}
// Step 6: Check for suspicious patterns
if hasSuspiciousPattern([segment1, segment2, segment3]) {
return ValidationResult(
isValid: false,
level: level,
error: .suspiciousKey
)
}
return ValidationResult(
isValid: true,
level: level,
error: nil
)
}
// MARK: - Helper Methods
private func isValidFormat(_ key: String) -> Bool {
// Check basic format with regex
let regex = try! NSRegularExpression(pattern: keyPattern)
let range = NSRange(key.startIndex..., in: key)
return regex.firstMatch(in: key, range: range) != nil
}
private func parseLicenseLevel(_ code: String) -> LicenseLevel? {
switch code {
case "L1": return .level1
case "L2": return .level2
default: return nil
}
}
private func verifyChecksum(_ baseKey: String, expectedLevel: LicenseLevel) -> Bool {
// Use dedicated checksum verifier
let segments = baseKey.split(separator: "-").dropFirst().map(String.init)
return checksumVerifier.verify(
baseKey: baseKey,
segments: segments,
level: expectedLevel
)
}
private func extractEmbeddedChecksum(from key: String) -> String {
// Checksum is cleverly embedded in the key segments
// This is a simplified representation
let segments = key.split(separator: "-").dropFirst()
var checksum = ""
for (index, segment) in segments.enumerated() {
// Extract specific character positions based on index
let position = (index * 2) % segment.count
let char = segment[segment.index(segment.startIndex, offsetBy: position)]
checksum.append(char)
}
return checksum
}
private func hasSuspiciousPattern(_ segments: [String]) -> Bool {
let suspiciousPatterns = [
"AAAA", "1111", "1234", "TEST",
"DEMO", "XXXX", "0000", "HACK"
]
for segment in segments {
// Check against known bad patterns
if suspiciousPatterns.contains(segment) {
return true
}
// Check if all characters are the same
if Set(segment).count == 1 {
return true
}
// Check for sequential characters
if isSequential(segment) {
return true
}
}
return false
}
private func isSequential(_ str: String) -> Bool {
let chars = Array(str)
for i in 1..<chars.count {
let prevValue = chars[i-1].asciiValue ?? 0
let currValue = chars[i].asciiValue ?? 0
if currValue != prevValue + 1 {
return false
}
}
return true
}
private func constantTimeCompare(_ a: String, _ b: String) -> Bool {
// Prevent timing attacks
guard a.count == b.count else { return false }
var result = 0
for (charA, charB) in zip(a, b) {
result |= Int(charA.asciiValue ?? 0) ^ Int(charB.asciiValue ?? 0)
}
return result == 0
}
}
// MARK: - Checksum Calculator
// MARK: - Checksum Verifier
struct ChecksumVerifier {
private let calculator = ChecksumCalculator()
func verify(baseKey: String, segments: [String], level: LicenseLevel) -> Bool {
// Calculate expected checksum
let expectedChecksum = calculator.calculate(baseKey, level: level)
// Extract embedded checksum from segments
let extractedChecksum = extractChecksum(from: segments)
// Constant-time comparison to prevent timing attacks
return constantTimeCompare(expectedChecksum, extractedChecksum)
}
private func extractChecksum(from segments: [String]) -> UInt32 {
var checksum: UInt32 = 0
for (index, segment) in segments.enumerated() {
let position = calculateExtractionPosition(index)
let char = segment[segment.index(segment.startIndex, offsetBy: position)]
// Extract bits from character
let bits = extractBitsFromChar(char)
checksum |= (bits << (index * 8))
}
return checksum
}
private func calculateExtractionPosition(_ index: Int) -> Int {
// Use prime numbers for better distribution
return (index * 31) % 4
}
private func extractBitsFromChar(_ char: Character) -> UInt32 {
// Extract embedded bits from character
guard let ascii = char.asciiValue else { return 0 }
return UInt32(ascii) & 0xFF
}
private func constantTimeCompare(_ a: UInt32, _ b: UInt32) -> Bool {
// Prevent timing attacks by always taking the same time
var result: UInt32 = 0
for i in 0..<4 {
let aByte = UInt8((a >> (i * 8)) & 0xFF)
let bByte = UInt8((b >> (i * 8)) & 0xFF)
result |= UInt32(aByte ^ bByte)
}
return result == 0
}
}
// MARK: - Checksum Calculator
struct ChecksumCalculator {
private let salt = Data("VoiceUwU2024KeyGen!@#$%".utf8)
func calculate(_ baseKey: String, level: LicenseLevel) -> UInt32 {
// Combine key components
let combined = baseKey + level.rawValue
let data = Data(combined.utf8)
// Add salt for security
var hasher = SHA256()
hasher.update(data)
hasher.update(salt)
// Generate hash
let hash = hasher.finalize()
// Convert to UInt32 checksum
let checksum = hash.withUnsafeBytes { bytes in
bytes.bindMemory(to: UInt32.self).first ?? 0
}
return checksum
}
}
// MARK: - Validation Cache
actor ValidationCache {
private var cache: LRUCache<String, ValidationResult>
private var stats = ValidationStats()
init(capacity: Int) {
self.cache = LRUCache(capacity: capacity)
}
func validate(_ key: String) async -> ValidationResult {
// Check cache first
if let cached = cache.get(key) {
stats.cacheHits += 1
return cached
}
stats.cacheMisses += 1
// Perform validation
let result = KeyValidator().validate(key)
// Cache result
cache.set(key, value: result)
return result
}
func getCacheStats() -> ValidationStats {
return stats
}
}
struct ValidationStats {
var cacheHits: Int = 0
var cacheMisses: Int = 0
var hitRate: Double {
let total = cacheHits + cacheMisses
return total > 0 ? Double(cacheHits) / Double(total) : 0
}
}
struct LRUCache<Key: Hashable, Value> {
private let capacity: Int
private var cache: [Key: Value] = [:]
private var order: [Key] = []
init(capacity: Int) {
self.capacity = capacity
}
mutating func get(_ key: Key) -> Value? {
guard let value = cache[key] else { return nil }
// Move to end (most recently used)
order.removeAll { $0 == key }
order.append(key)
return value
}
mutating func set(_ key: Key, value: Value) {
// Remove oldest if at capacity
if cache.count >= capacity && cache[key] == nil {
if let oldest = order.first {
cache.removeValue(forKey: oldest)
order.removeFirst()
}
}
cache[key] = value
order.removeAll { $0 == key }
order.append(key)
}
}
```
## Validation Rules
1. **Format Rules**
- Must start with "VUUW"
- Three segments of 4 alphanumeric characters
- End with L1 or L2
- Only uppercase letters and numbers
- No O, 0, I, 1 to avoid confusion
2. **Checksum Rules**
- Checksum embedded in key segments
- Uses product ID + segments + level for calculation
- Salt added for security
- Constant-time comparison
3. **Security Rules**
- No obvious patterns (AAAA, 1234, etc.)
- No all-same characters
- No sequential patterns
- No test/demo keys in production
## Error Handling
- `invalidFormat`: Key doesn't match expected pattern
- `wrongProduct`: Not a VoiceUwu key
- `unsupportedLevel`: Level code not L1 or L2
- `checksumMismatch`: Failed checksum verification
- `suspiciousKey`: Contains suspicious patterns