11 KiB
11 KiB
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
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
-
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
-
Checksum Rules
- Checksum embedded in key segments
- Uses product ID + segments + level for calculation
- Salt added for security
- Constant-time comparison
-
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 patternwrongProduct: Not a VoiceUwu keyunsupportedLevel: Level code not L1 or L2checksumMismatch: Failed checksum verificationsuspiciousKey: Contains suspicious patterns