1import 'dart:math'; 2import 'dart:typed_data'; 3 4import 'package:crypto/crypto.dart' as crypto; 5 6import '../runtime/runtime_implementation.dart'; 7import '../utils/lock.dart'; 8import 'flutter_key.dart'; 9 10/// Flutter implementation of RuntimeImplementation. 11/// 12/// Provides cryptographic operations for OAuth flows using: 13/// - pointycastle for EC key generation (via FlutterKey) 14/// - crypto package for SHA hashing 15/// - Random.secure() for cryptographically secure random values 16/// - requestLocalLock for concurrency control 17/// 18/// This implementation supports: 19/// - ES256, ES384, ES512, ES256K (Elliptic Curve algorithms) 20/// - SHA-256, SHA-384, SHA-512 (Hash algorithms) 21/// - Secure random number generation 22/// - Local (in-memory) locking for token refresh 23/// 24/// Example: 25/// ```dart 26/// final runtime = FlutterRuntime(); 27/// 28/// // Generate a key 29/// final key = await runtime.createKey(['ES256', 'ES384']); 30/// 31/// // Hash some data 32/// final hash = await runtime.digest( 33/// Uint8List.fromList([1, 2, 3]), 34/// DigestAlgorithm.sha256(), 35/// ); 36/// 37/// // Generate random bytes 38/// final random = await runtime.getRandomValues(32); 39/// ``` 40class FlutterRuntime implements RuntimeImplementation { 41 /// Creates a FlutterRuntime instance. 42 const FlutterRuntime(); 43 44 @override 45 RuntimeKeyFactory get createKey { 46 return (List<String> algs) async { 47 return FlutterKey.generate(algs); 48 }; 49 } 50 51 @override 52 RuntimeDigest get digest { 53 return (Uint8List bytes, DigestAlgorithm algorithm) async { 54 switch (algorithm.name) { 55 case 'sha256': 56 case 'SHA-256': 57 return Uint8List.fromList(crypto.sha256.convert(bytes).bytes); 58 59 case 'sha384': 60 case 'SHA-384': 61 return Uint8List.fromList(crypto.sha384.convert(bytes).bytes); 62 63 case 'sha512': 64 case 'SHA-512': 65 return Uint8List.fromList(crypto.sha512.convert(bytes).bytes); 66 67 default: 68 throw UnsupportedError( 69 'Unsupported digest algorithm: ${algorithm.name}', 70 ); 71 } 72 }; 73 } 74 75 @override 76 RuntimeRandomValues get getRandomValues { 77 return (int length) async { 78 final random = Random.secure(); 79 return Uint8List.fromList( 80 List.generate(length, (_) => random.nextInt(256)), 81 ); 82 }; 83 } 84 85 @override 86 RuntimeLock get requestLock { 87 // Use the local lock implementation from utils/lock.dart 88 // This prevents concurrent token refresh within a single isolate 89 return requestLocalLock; 90 } 91}