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

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

  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