Jump to content

Kas Ob.

Members
  • Content Count

    503
  • Joined

  • Last visited

  • Days Won

    9

Kas Ob. last won the day on April 13

Kas Ob. had the most liked content!

Community Reputation

134 Excellent

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Kas Ob.

    TWSocket,,,

    Please, pretty please, make it [0..63] not [0..64], it is triggering my OCD ! Also having goosebumps from that off by one to an odd number !
  2. I think 48 was there and the code changed and that comment along that excerpt stayed, Anyhow, the random generation algorithm is LCG, and it is fast and enough for general purposes, it is like PCG https://en.wikipedia.org/wiki/Permuted_congruential_generator , also there is many others, they are fast, extremely fast but they are not cryptographically secure, what does that means ? It means if i get hold on few (or lot, it depends) of the output random of that algorithm then i can predict the exact state (seed) at that moment, hence i can predict all the future random output. Why this is critically insecure ? I will give an example, in TLS connection key are randomly generated (private keys), while only public key are sent over the wire and they can NOT compromise the private key but there is different things in the SSL/TLS header that can help break the private key, if the software is using weak random generator like LCG then it also will be used in the sessionID and in the IV and nonces ..etc that are plainly sent in the TLS header for the handshake, hence if the attacker predicted the state then it at least he can just produce random numbers and all your private keys (future ones) are exposed. LCG is fins for general big numbers library but it can not be used with PKI and any cryptographic library/implementation, as you are using RSA, then for your own learning it is fine, but do not trust its random or key coming form it. ps : in the mentioned library LCG is defined as form here https://en.wikipedia.org/wiki/Permuted_congruential_generator and constants are a,c and m , you can see them here https://github.com/rvelthuis/DelphiBigNumbers/blob/master/Source/Velthuis.RandomNumbers.pas#L116C1-L136C5 m is a little not so obvious but it is in the bit shift meaning m=64-Bits rendering, with this known and as Bits is used in Next which called with three variant 31,32 and 64, all this values just render it more predictable, at 32 all you need is somethign around 32 byte to calculate the state (seed) ! also SessionID in TLS is 32byte ! meaning with the wrong PRNG it is enough to predict the exact state and predict the all exact private keys, breaking the secure connection alltogether. Also 48 bits (the comment) it should reflect on 64-Bits (or Bits) being 48, but i don't see that anywhere, may it was there in the past.
  3. Kas Ob.

    TWSocket,,,

    I believe the needed buffer is 56 (2*28) for IPv6 so [0..55] bytes should be enough, if i am not missing something.
  4. Kas Ob.

    TWSocket,,,

    I forgot to mention important thing about that structure and its size. You can't and must not put it on the stack !, it will overflow and destroy/corrupt the stack, so it must be on the heap and must be zeroed before usage as best practice, because there is two addresses (pointing to two structures) will be filled by that API and it will put them right after the initial structure and fix the addresses.
  5. Kas Ob.

    TWSocket,,,

    Here a fully working example, modified from a code for different thing, yet it shows successful use of SO_BSP_STATE unit uReadSocketInfo; interface uses Windows, Winsock2; function WSAInitialize(MajorVersion, MinorVerion: Integer): Boolean; function WSADeInitialize: Boolean; function CheckTCPPortNB(const IP: string; Port: Integer; out TimeMS: Integer): Boolean; var CHECKPOINT_TIMEOUT_MS: integer = 1000; implementation procedure GetSocketInformation(s: TSocket); var pSockAddresssI: PCSADDR_INFO; Res, WsaLError, OptLen: Integer; begin OptLen := SizeOf(CSADDR_INFO) + 128; // yes the original size is 24, but more is needed and will fail on 24 // for IPv4 an extra of 32 bytes is enough instead of 128 pSockAddresssI := GetMemory(OptLen); try Res := getsockopt(s, SOL_SOCKET, SO_BSP_STATE, PAnsiChar(pSockAddresssI), OptLen); if Res = SOCKET_ERROR then WsaLError := WSAGetLastError else Writeln('Socket information :'); finally FreeMemory(pSockAddresssI); end; end; function CheckTCPPortNB(const IP: string; Port: Integer; out TimeMS: Integer): Boolean; var s: TSocket; Addr: TSockAddrIn; SAddr: TSockAddr absolute Addr; QPF, QPC1: Int64; NonBlockMode: DWORD; Res: Integer; FDW, FDE: fd_set; TimeVal: TTimeVal; function GetElapsedTime: Integer; var QPC2: Int64; begin QueryPerformanceCounter(QPC2); Result := (QPC2 - QPC1) div (QPF div 1000); end; begin Result := False; TimeMS := 0; s := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if s = INVALID_SOCKET then Exit; NonBlockMode := 1; ioctlsocket(s, Integer(FIONBIO), NonBlockMode); Addr.sin_family := AF_INET; Addr.sin_addr.S_addr := inet_addr(PAnsiChar(AnsiString(IP))); Addr.sin_port := htons(Port); QueryPerformanceFrequency(QPF); QueryPerformanceCounter(QPC1); Res := connect(s, SAddr, SizeOf(SAddr)); if (Res = SOCKET_ERROR) and (WSAGetLastError = WSAEWOULDBLOCK) then begin TimeVal.tv_sec := 0; // 1 sec = 1000000 usec TimeVal.tv_usec := 1000; // 1 ms = 1000 usec repeat FDW.fd_count := 1; FDW.fd_array[0] := s; FDE.fd_count := 1; FDE.fd_array[0] := s; TimeMS := GetElapsedTime; Res := select(1, nil, @FDW, @FDE, @TimeVal); until (Res > 0) or (TimeMS >= CHECKPOINT_TIMEOUT_MS); end; Result := (FDW.fd_count = 1) and (FDE.fd_count = 0); /// we have connected socket with full valid information if Result then begin GetSocketInformation(s); end; /// TimeMS := GetElapsedTime; if s <> INVALID_SOCKET then closesocket(s); end; function WSAInitialize(MajorVersion, MinorVerion: Integer): Boolean; var WSA: TWsaData; begin Result := WSAStartup(MakeWord(MajorVersion, MinorVerion), WSA) = 0; if Result then begin Result := (Byte(WSA.wVersion shr 8) = MinorVerion) and (Byte(WSA.wVersion) = MajorVersion); if not Result then begin Result := False; WSADeInitialize; end; end; end; function WSADeInitialize: Boolean; begin Result := WSACleanup = 0; end; initialization WSAInitialize(2, 2); finalization //WSADeInitialize; end. a small project to use it program SocketInformation; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, uReadSocketInfo in 'uReadSocketInfo.pas'; var Time : Integer; begin try CheckTCPPortNB('142.251.36.46', 80, Time); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. Put a break point with debugger on the getsockopt and you will get 32 bytes additional bytes (on top the 24 bytes, the structure size) is needed for IPv4 so i suspect more is needed for IPv6, this is undocumented behavior.
  6. Literally the definition of Karatsuba, to split in half and perform on half length thus reducing the complexity of time needed not the complexity of the implementation, in case of 64bit then only two half is needed with no recursion, Wikipedia page explain it, but there is simpler resources on the Internet to explain it. Fun fact : There is also an algorithm named Toom-Cook https://en.wikipedia.org/wiki/Toom–Cook_multiplication reduce the multiplication further but increase the complexity of implementation more, both algorithm shift the operation into smaller part reducing the need for multiplication carry but increase the addition operation with its carry. Just common knowledge to whom may be interested. Yes it is simple, but if you want the most beautiful mathematically algorithm (i see it like that), is El-Gamal (sometimes written (ElGamal), and once you built your RSA you will find implementing ElGamal is relatively close and not any more a complex task, as you will need the little different or adjusted arithmetic, i mean you will have primality test along with GCD (GCD might be needed but that depend on your approach or method), ElGamal has a feature which can be used with Elliptic Curve and their finite fields hence decreasing the length of the keys substantially, so it might interest you and your friends ! https://en.wikipedia.org/wiki/ElGamal_encryption https://en.wikipedia.org/wiki/ElGamal_signature_scheme A little more detailed resources https://www.geeksforgeeks.org/elgamal-encryption-algorithm/ https://compare-encryption-algorithms.mojoauth.com/rsa-4096-vs-elgamal-variable-key-size/ Yup, nothing beats Miller–Rabin test in speed, it looks nice book. Focus on RSA !, ElGamal will need different beast https://en.wikipedia.org/wiki/Modular_exponentiation but after RSA you will find it easy as it is pretty straight forward as listed in Wikipedia. Again good luck.
  7. I don't have any of the mentioned above IDEs, but i see a problem or two .. well more than that a lot, but will talk about your exact problem first 1) The directives are wrong and mixed, and here how they should look like function TRandom.Next(Bits: Integer): UInt32; begin {$IFOPT R+} {$DEFINE HasRangeChecks} {$ENDIF} {$IFOPT Q+} {$DEFINE HasOverflowChecks} {$ENDIF} {$RANGECHECKS OFF} {$OVERFLOWCHECKS OFF} FSeed := (FSeed * CMultiplier + CIncrement); Result := UInt32(FSeed shr (64 - Bits)); // Use the highest bits; Lower bits have lower period. {$IFDEF HasRangeChecks} {$RANGECHECKS ON} {$ENDIF} {$IFDEF HasOverflowChecks} {$OVERFLOWCHECKS ON} {$ENDIF} end; Because we have two overflow check can be triggered here, not one !, Integer overflow range overflow come from multiplication and form truncation while mixing signed and unsigned, both need to be disabled, also the R+ for the range while wrongly was Q. 2) I tried this small test procedure RunTest; var Rand: IRandom; A, B, C: BigInteger; begin Rand := TRandom.Create($FF00FE01FD02FC03); // sooner ! Trigger overflow check at TRandomBase.NextBytes //Rand := TRandom.Create($FF00FF01FF02FF03); // Trigger overflow check at TRandom.Next A.Create(1024, Rand); B.Create(1024, Rand); C := A * C; Writeln('A = ' + A.ToHexString); Writeln('B = ' + B.ToHexString); Writeln('C = ' + C.ToHexString); end; And we have another place that has an overflow, but the fix is easy (again sign bit!!) procedure TRandomBase.NextBytes(var Bytes: array of Byte); var Head, Tail: Integer; N, {Rnd,} I: Integer; Rnd : UInt32; // <--- fix overflow begin Didn't go through more tests or any deeper in digging into the source. Now to the other problems 3) This pseudorandom number generator is not cryptographically secure , it has very small duration and depend on single modular operation which is 2^(64-Bits)= 2^k, this can't be considered secure it is as predictable as it can be by design, but choosing 2^k make brute force algorithm for it way much faster ! 4) I don't understand from where the assumption of only 48 bits are only used, this is strange and out of the context or this family of PRNG, may be i missed something with Bits, but will not dig deeper in it. 5) the core problem is depending on Int64, this is signed and by using signed we lose a bit and confuse the compiler and math, while gains nothing in return, this family of PRNG which call LCG https://en.wikipedia.org/wiki/Linear_congruential_generator doesn't handle signed numbers, and doesn't need as it is by definition, so using Int64 should be replaced with UInt64 for the constants, and the algorithm too. 6) tried to figure out this code You are going with Karatsuba https://en.wikipedia.org/wiki/Karatsuba_algorithm , nice it is the right way when you are in the corner, also much cleaner for limbs, yet the last masking is again wrong assuming (you are following the original code) it can or should be signed operation, this should be changed to unsigned, and return the sign bit to the fold, as it is by design is using the highest 32 bit, by losing the sign, where entropy is lost, we left with 31 bit randomness. About learning and implementing RSA, yes do it and you will learn much, and i wish you good luck, also a suggestion : why not read more about CSPRNG and implement one ,a cryptographically secure (CS) one, there is one i liked very much due it speed and portability, it is based on CHAHCA with reduced rounds called ChaCha8, it use the same permutation as ChaCha20 but with 8 rounds, it is secure and small as it can be, and used in Go Lang applications extensively, anyway it is not so important and most important thing is understanding is that security is like a chain and the chain is weak as its weakest link, randomness is always the most crucial link that when break (insecure) it will render everything built on it insecure, and last suggestion if you are going to use you own implementation of RSA in production for clients then test it then test it and test it again and think a lot before using your own implementation, it is not recommended by anyone ( as i think you read again and again, things like don't implement your own...), but you should learn it inside out, so go with it.
  8. I am intrigued here !, And really want to ask this , Did you asked any AI for solution ? Because the solution is very simple unless there is something missing or the ssh library is broken, it could be broken on both client and server, but what concern me is what server SSH is being used, and few numbers will be great to understand this. Anyway, my first suggestion is to hack your way into it, well it is a workaround to guarantee the TCP socket connection is alive and being pinged, just add another channel for port forwarding if that is allowed on server side, this should solve your problem and enforce ping for that channel on that socket to be communicated hence stopping the timeout, well unless the timeout is coming from different cause and has nothing to do with SSH per se. Also what are the setting on server for keepalive interval and max count ?
  9. Not exactly, using ReportMemoryLeaksOnShutdown didnt take any leak running the tests… every queue format release their resources. Did not ran the code, and my test will be irrelevant on old IDE, but browsed the code and i can see a thing to point here, Anders might be right and you should investigate the fact you are not generating leaks or catching something worse, See, there is "FreeOnTerminate:= True;" in the constructor in few places and yet there is specific call to destroy, this should be bad mix, leaks and double freeing most likely will be there, well unless TThread and RTL have changed a lot since XE8, and in that case just ignore this post.
  10. Kas Ob.

    Best way of handling Exceptions

    Not at all, specially Delphi RTL is plagued with exceptions, something to live with, but don't add more, and don't depend on re-raise, when possible handle in place or encapsulate these handlers then delegate if needed. In other words, just don't complicate the exception thing, personal view after all, like for me choosing between library that raise exception and one handle failure gracefully with event, also when designing a interface/class then an event for failure will relief any one will use it from worrying about exception. And yes this is way off topic, and sorry for that.
  11. Kas Ob.

    Best way of handling Exceptions

    That would the perfect code and most safest one. Raising exception for error, any error, that is wrong in my opinion, take file handling, yes we are in era that files and drives are mounted and removable, so why raising exception, it is error or just failure, exception should indicate critical problem not simple operation that can happen any time and should be expected to begin with, like lost TCP connection why the exception it is error (or failure) and happen all the time, it is expected, so handle it gracefully and try to re-connect or something, but not violate the whole logic flow using raising exception, same goes with DB operations, lost connection to server or failed SQL, while lost server connection is or should be expected and not exception, bad SQL could be raising exception to prevent data corruption, then halt the whole if possible or just log it to be prevented in future,. Losing server connection can't be prevented by code or its developer, and that is the difference between error and exception, unlike bad/broken SQL, an error here means the code is missing edge cases or sanitizing the data or...., well in my opinion. I don't want to steer this thread far form OP topic about specific structure argument with AI, but exceptions in my opinion is not far from using GOTO !, well one can say it is very similar trapped/targeted GOTO, is GOTO illegal ? no , it is unavoidable in some cases, but is it recommended ? no.
  12. Kas Ob.

    Best way of handling Exceptions

    That is perfect and the right way, but don't validate e:exception or any parameter inside except..end; just ship them somewhere that already has its own try..except, thus safely can be handled and logged (by handled i mean the exception itself and its log), inside the original you can use a boolean to exit gracefully locally (that also can be returned as parameter or as a result) instead of depend on "raise" to exit the branch the code in, start with these places you mentioned that need log expanding.
  13. Kas Ob.

    Best way of handling Exceptions

    I have thoughts on this subject and this code and its approach, specially about raise in except..end clause or re-raising, 1) OS(s) are evolving, like Windows, it is getting harsher by version against exceptions in particular, specially the ones that require long unwind, that code could raise and take the application with it, it is portability is question too, might work just perfectly in production then you refactor that code now the "raise" unwinding involve a trip to OS then back at least once and the OS with its new protection (CFG, SafeSEH...) could trigger killing the application in rare moment and leaving non useful report. 2) Your code is assuming the exception is solemnly is coming from "sqhpartyroles", so what if the exception has different origin like page fault or zero division, your raising and message just obfuscating the whole thing and confusing the error message and the logs. 3) Inside the except..end you are assuming sqhpartyroles is still nice and accessible, what happen when sqhpartyroles.sql is toast, an unintended exception will be raised from here in, and sending you in witch hunt. 4) Delphi is object oriented, and it is all about encapsulation, while re-raise or catch and raise is more like leftover form past era or functional programming, exception are not for signaling failure (passing through) or passing data. "raise;" is not dangerous per se, but not much useful too, it is a short cut (may be ), i would suggest to redesign you exception handling, centralized or not, You could either 1) Extended these objects you doubt that can raise exception, into they catch their own exception and pass them to newly introduced object/class as handler for exception, as example extend your TSQLQuery and add a property for TMyAppExceptionHandler... 2) centralize the SQL execution/opening into special object that have in the parameter everything from the TSqlQuery, TTable.... then open or execute, and it will handle the execution and exceptions there, in-place. 3) (2) could be a function instead of class/object, i like it thread safe and globally accessible. 4) The code responsible for performing the SQL operation will call the exception handler with exception object and its parameter (which could be the parameter for itself), then that code is also protected/shielded from raising exception inside try..except, thus you have solid exception handling, even that second try..except is nested one to make sure even when handling is went in worst case scenario then at least a log with "fatal exception in handling SQL exception at xxxxx".
  14. Kas Ob.

    EnumFontFamiliesEx...

    from https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-one/64e2db6e-6eeb-443c-9ccf-0f72b37ba411 This doesn't seem right !
  15. One small addition to Remy detailed answer, There is zero guarantee that DllMain will be called from the the Main Thread or even the the same thread that called LoadLibrary ! So all bets are off using VCL, while RTL should be OK if thread safety used with it (locking/synchro..)
×