import JVMTypes = require('../../includes/JVMTypes'); import * as Doppio from '../doppiojvm'; import JVMThread = Doppio.VM.Threading.JVMThread; import ArrayClassData = Doppio.VM.ClassFile.ArrayClassData; import ReferenceClassData = Doppio.VM.ClassFile.ReferenceClassData; import logging = Doppio.Debug.Logging; import util = Doppio.VM.Util; import IJVMConstructor = Doppio.VM.ClassFile.IJVMConstructor; import * as NodeCrypto from 'crypto'; declare var registerNatives: (defs: any) => void; declare var msCrypto: Crypto; class doppio_Debug { public static 'SetLogLevel(Ldoppio/Debug$LogLevel;)V'(thread: JVMThread, loglevel: JVMTypes.doppio_Debug$LogLevel): void { logging.log_level = loglevel['doppio/Debug$LogLevel/level']; } public static 'GetLogLevel()Ldoppio/Debug$LogLevel;'(thread: JVMThread): JVMTypes.doppio_Debug$LogLevel { var ll_cls = (> thread.getBsCl().getInitializedClass(thread, 'Ldoppio/Debug$LogLevel;')).getConstructor(thread); switch (logging.log_level) { case 10: return ll_cls['doppio/Debug$LogLevel/VTRACE']; case 9: return ll_cls['doppio/Debug$LogLevel/TRACE']; case 5: return ll_cls['doppio/Debug$LogLevel/DEBUG']; default: return ll_cls['doppio/Debug$LogLevel/ERROR']; } } } class doppio_JavaScript { public static 'eval(Ljava/lang/String;)Ljava/lang/String;'(thread: JVMThread, to_eval: JVMTypes.java_lang_String): JVMTypes.java_lang_String { try { var rv = eval(to_eval.toString()); // Coerce to string, if possible. if (rv != null) { return util.initString(thread.getBsCl(), "" + rv); } else { return null; } } catch (e) { thread.throwNewException('Ljava/lang/Exception;', `Error evaluating string: ${e}`); } } } class doppio_security_BrowserPRNG { private static crypto = typeof(crypto) !== 'undefined' ? crypto : typeof(msCrypto) !== 'undefined' ? msCrypto : null; public static 'isAvailable()Z'(thread: JVMThread): boolean { // !! makes it a boolean. const crypto = doppio_security_BrowserPRNG.crypto; return !!(crypto && crypto.getRandomValues); } public static 'engineSetSeed([B)V'(thread: JVMThread, javaThis: JVMTypes.doppio_security_BrowserPRNG, seed: JVMTypes.JVMArray): void { thread.throwNewException('Ljava/security/ProviderException;', 'engineSetSeed() failed.'); } public static 'engineNextBytes([B)V'(thread: JVMThread, javaThis: JVMTypes.doppio_security_BrowserPRNG, bytes: JVMTypes.JVMArray): void { const crypto = doppio_security_BrowserPRNG.crypto; crypto.getRandomValues( bytes.array); } public static 'engineGenerateSeed(I)[B'(thread: JVMThread, javaThis: JVMTypes.doppio_security_BrowserPRNG, numBytes: number): JVMTypes.JVMArray { const crypto = doppio_security_BrowserPRNG.crypto; const bytes = util.newArrayFromClass(thread, > thread.getBsCl().getInitializedClass(thread, '[B'), numBytes); crypto.getRandomValues( bytes.array); return bytes; } } class doppio_security_NodePRNG { public static 'isAvailable()Z'(thread: JVMThread): boolean { return !util.are_in_browser(); } public static 'engineSetSeed([B)V'(thread: JVMThread, javaThis: JVMTypes.doppio_security_NodePRNG, seed: JVMTypes.JVMArray): void { thread.throwNewException('Ljava/security/ProviderException;', 'engineSetSeed() failed.'); } public static 'engineNextBytes([B)V'(thread: JVMThread, javaThis: JVMTypes.doppio_security_NodePRNG, bytes: JVMTypes.JVMArray): void { const array = bytes.array; const len = array.length; const data = NodeCrypto.randomBytes(len); for (let i = 0; i < len; i++) { array[i] = data.readInt8(i); } } public static 'engineGenerateSeed(I)[B'(thread: JVMThread, javaThis: JVMTypes.doppio_security_NodePRNG, numBytes: number): JVMTypes.JVMArray { const data = NodeCrypto.randomBytes(numBytes); const array = util.buff2i8(data); return util.newArrayFromDataWithClass(thread, > thread.getBsCl().getInitializedClass(thread, '[B'), array); } } registerNatives({ 'doppio/Debug': doppio_Debug, 'doppio/JavaScript': doppio_JavaScript, "doppio/security/BrowserPRNG": doppio_security_BrowserPRNG, "doppio/security/NodePRNG": doppio_security_NodePRNG });