Jump to content

Davide Angeli

Members
  • Content Count

    116
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by Davide Angeli


  1. 5 hours ago, juanluanaya said:

    Hi Davide, Could you help me out with the code of SBBSoapSignAndEncryptWithJKS?

    Hi, this is what is working for me. You'll probably need to adapt it because it is built based on my needs, but I hope it can be a good starting point for you.

     

    // Returns 0 = ok (sign and encrypt is fine)
    //         1 = failed open keystore to sign/encrypt
    //         2 = failed to load sing/encryption certificate
    function SBBSoapSignAndEncryptJKS(const InputFilename, OutputFilename, JKSFileName : String; OnPasswordNeeded : TPasswordNeededEvent; out Error : String; DebugSign : Boolean = FALSE) : Integer;
    var
      XMLEncryptor : TsbxXMLEncryptor;
      SOAPSigner : TsbxSOAPSigner;
      NSItem : TsbxXMLNamespace;
      sCSerialNumber,sIssuer : String;
    
    begin
      Result:=0;
      Error:='';
    
      // calculate some IDs and variables for debug purpose
      var BinarySecurityTokenID:='X509-'+FormatDateTime('yyyymmddhhnnsszzz',Now);
      var BodyReference:='ID-'+FormatDateTime('yyyymmddhhnnsszzz',Now);
      var EncryptedDataID:='ED-'+FormatDateTime('yyyymmddhhnnsszzz',Now);
      var EncryptedKeyID:='EK-'+FormatDateTime('yyyymmddhhnnsszzz',Now);
    
      // some temporary variables to handle debug filenames
      var BasePath:=ExtractFilePath(OutputFileName);
      var BaseFileName:=ExtractFileName(InputFileName);
      BaseFileName:=BaseFileName.SubString(0,BaseFileName.IndexOf('.'));
    
      XMLEncryptor := TsbxXMLEncryptor.Create(nil);
      SOAPSigner := TsbxSOAPSigner.Create(nil);
      try
        /// Step 1
        /// Signing body element
        var CertificateStorage := TsbxCertificateStorage.Create(Nil);
        try
          try
            CertificateStorage.OnPasswordNeeded:=OnPasswordNeeded;
            CertificateStorage.Open('java://'+JKSFileName);
            if CertificateStorage.Opened then begin
               CertificateStorage.Select('*',True,1);
               SOAPSigner.SigningCertificate:=CertificateStorage.SelectedCertificates[0];
            end else begin
               Result:=1; Error:='Failed to open keystore to sign';
               Exit;
            end;
          except
            on E: Exception do
            begin
              Result:=2; Error:='Failed to signing load certificate: ' + E.Message;
              Exit;
            end;
          end;
        finally
          FreeAndNil(CertificateStorage);
        end;
    
        SOAPSigner.InputFile := InputFilename;
        SOAPSigner.InputBytes := SOAPSigner.OutputBytes;
    
        SOAPSigner.NewSignature.SignatureType := sstWSSSignature;
        SOAPSigner.NewSignature.HashAlgorithm := 'SHA1';
        SOAPSigner.NewSignature.XAdES := false;
        SOAPSigner.SecurityHeaderIndex := -1;
    
        var k := SOAPSigner.AddBodyReference(BodyReference, false);
        SOAPSigner.References[k].InclusiveNamespacesPrefixList := 'xsd xsi';
        SOAPSigner.Config('KeyInfoID=KI-'+FormatDateTime('yyyymmddhhnnsszzz',Now));
        SOAPSigner.Config('SecurityTokenReferenceID=STR-'+FormatDateTime('yyyymmddhhnnsszzz',Now));
        SOAPSigner.Config('BinarySecurityTokenID='+BinarySecurityTokenID);
        SOAPSigner.Config('InclusiveNamespacesPrefixList=SOAP-ENV xsd xsi');
        SOAPSigner.Config('PrependCustomXML=<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="TS-'+FormatDateTime('yyyymmddhhnnsszzz',Now)+'">' +
                                             '<wsu:Created>'+DateToISO8601(Now,False)+'</wsu:Created>' +
                                             '<wsu:Expires>'+DateToISO8601(IncMinute(Now,50),False)+'</wsu:Expires>' +
                                            '</wsu:Timestamp>');
        SOAPSigner.Sign;
    
        // - just for debug purpose save the signed result
        if DebugSign then
           TFile.WriteAllBytes(BasePath+BaseFileName+'signed.xml', SOAPSigner.OutputBytes);
    
        ///  Step 2
        ///  Encrypting body element
        CertificateStorage := TsbxCertificateStorage.Create(Nil);
        try
          try
            CertificateStorage.OnPasswordNeeded:=OnPasswordNeeded;
            CertificateStorage.Open('java://'+JKSFileName);
            if CertificateStorage.Opened then begin
               XMLEncryptor.KeyEncryptionCertificate:=CertificateStorage.Certificates[1];
               sCSerialNumber:=TBytesSerialToInt64(XMLEncryptor.KeyEncryptionCertificate.SerialNumber).ToString;
               sIssuer:=XMLEncryptor.KeyEncryptionCertificate.IssuerRDN;
    
               var a:=sIssuer.Split(['/']);
               Delete(a,0,1);
               sIssuer:='';
               for var J:=High(a) downto Low(a) do begin
                   if Not sIssuer.IsEmpty then sIssuer:=sIssuer+',';
                   sIssuer:=sIssuer+a[J];
               end;
            end else begin
              Result:=1; Error:='Failed to open keystore to encrypt';
              Exit;
            end;
          except
            on E: Exception do
            begin
              Result:=2; Error:='Failed to load encrypt certificate: ' + E.Message;
              Exit;
            end;
          end;
        finally
          FreeAndNil(CertificateStorage);
        end;
    
        XMLEncryptor.InputBytes := SOAPSigner.OutputBytes;
    
        XMLEncryptor.XMLNode := '/SOAP-ENV:Envelope/SOAP-ENV:Body';
        XMLEncryptor.EncryptedDataType := cxedtContent;
        XMLEncryptor.EncryptionMethod := 'AES128';
        XMLEncryptor.EncryptKey := true;
        XMLEncryptor.KeyEncryptionType := cxetKeyTransport;
        XMLEncryptor.KeyTransportMethod := cxktRSAOAEP;
    
        XMLEncryptor.Config('EncryptedKeyID='+EncryptedKeyID);
        XMLEncryptor.Config('EncryptedDataID='+EncryptedDataID);
        XMLEncryptor.Config('EncryptedKeyXMLElement=/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security');
        XMLEncryptor.Config('KeyInfoCustomXML=<wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"'+
                                                                         ' xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"' +
                                                                         ' xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">' +
                                               '<wsse:Reference URI="#'+EncryptedKeyID+'"/>' +
                                              '</wsse:SecurityTokenReference>');
    
        XMLEncryptor.Config('EncryptedKeyInfoCustomXML=<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">' +
                                                       '<ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#">' +
                                                        '<ds:X509IssuerSerial>' +
                                                         '<ds:X509IssuerName>'{'CN='}+sIssuer+'</ds:X509IssuerName>' +
                                                         '<ds:X509SerialNumber>'+sCSerialNumber+'</ds:X509SerialNumber>' +
                                                        '</ds:X509IssuerSerial>' +
                                                       '</ds:X509Data>' +
                                                      '</wsse:SecurityTokenReference>');
    
        XMLEncryptor.Encrypt;
    
        ///  Step 3
        SOAPSigner.InputBytes := XMLEncryptor.OutputBytes;
        SOAPSigner.InputFile := '';
        SOAPSigner.OutputFile := OutputFilename;
        SOAPSigner.Open;
    
        // for XPath expressions we need to define prefixes used
        // prefixes: SOAP-ENV, xenc, wsu, ds - are already known by the component
        // wsse prefix better to define explicitly, since it is SOAP version specific
        NSItem := TsbxXMLNamespace.Create;
        try
          NSItem.Prefix := 'wsse';
          NSItem.URI := 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
          SOAPSigner.XPathNamespaces.Add(NSItem);
        finally
          FreeAndNil(NSItem);
        end;
    
        SOAPSigner.SetInnerXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/xenc:EncryptedKey',
          SOAPSigner.GetInnerXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/xenc:EncryptedKey') +
           '<xenc:ReferenceList>' +
            '<xenc:DataReference URI="#'+EncryptedDataID+'"/>' +
           '</xenc:ReferenceList>');
    
        SOAPSigner.SetInnerXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security',
          SOAPSigner.GetOuterXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/xenc:EncryptedKey') +
          SOAPSigner.GetOuterXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:BinarySecurityToken') +
          SOAPSigner.GetOuterXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsu:Timestamp') +
          SOAPSigner.GetOuterXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/ds:Signature')
        );
    
        SOAPSigner.Close(true);
    
      finally
        FreeAndNil(XMLEncryptor);
        FreeAndNil(SOAPSigner);
      end;
    end;

     


  2. 45 minutes ago, JonRobertson said:

    Between work and hobby, I use Delphi 11.3 over 50 hours a week, every week. I have half a dozen add-ons and over two dozen third-party component libraries installed, in addition to my own component library.

    I've been using Delphi for at least 30 years, often for 9 hours a day. In my humble opinion, the IDE's instability can also be attributed to the way we work, regardless of the tools and components installed, which may or may not be stable. It's a fact that since version 10, my preferred way of working, which I use for my main project, has been causing the IDE to crash with a wide variety of errors (the most common being F2084 Internal Error).

    My project uses runtime packages that I created, several DLLs, an EXE, and the IDE also has a package installed with components that I developed, which shares the aforementioned runtime packages. For convenience and speed, everything was enclosed in a single project group. When I maintained my component library, to apply changes to the entire group, I always worked by doing a "compile all" of everything in the group: runtime packages, visual component package, DLLs, and then the EXE. In this context, if there are any forms open in the IDE, the IDE's instability is amplified to the nth degree, and the error is almost systematic.

    Since Embarcadero is unable to fix these errors (it's almost impossible to provide a test situation to open a report), I've had to adapt by changing my system, even though it's more cumbersome for me: I first compile the runtime and design packages, now placed in another project group, and then compile the application (DLL, EXE) by continuously switching between the two project groups. In this way, the IDE rarely crashes. The critical point in my case is certainly when the IDE needs to unload the design package from memory in order to compile it, and it's clearly not able to handle the unloading of any open forms that use the components present in the package being compiled. This is my experience.

     

    And by the way, the menu item that's clicked the most in the latest versions (including 12.2) is "Reload LSP Server" because it just doesn't want to work as it should.

    • Sad 1

  3. Hi all,

     

    if I try a reverse assignement on a code like this one:

         O.F['v1']:=edV1.AsCurrency;                                                // RA - Value 1
         O.F['v2']:=edV2.AsCurrency;                                                // RA - Value 2
         O.F['v3']:=edV3.AsCurrency;                                                // RA - Value 3
         O.S['v4']:=edV4.AsString;                                                  // RA - Value 4
         O.S['v5']:=edV4.AsString;                                                  // RA - Value 5

    I got this one:

         edV1.AsCurrency := O.F['v1'];
         edV2.AsCurrency := // RA - Value 1 O.F['v2'];
         edV3.AsCurrency := // RA - Value 2 O.F['v3'];
         edV4.AsString := // RA - Value 3 O.S['v4'];
         edV4.AsString := // RA - Value 4 O.S['v5'];

    it seems to have problems with end-of-line comments. 

     

    Is this the right place to report bugs?


  4. I am also using the IDE on an HIDPI monitor and simultaneously on a regular one.

     

    I also find that the toolbars are all moved or gradually enlarged. In my case, it seems to me that the problem occurs when returning from a computer standby (returning from a lunch break) or even when only the monitor goes into standby because it has been inactive for a few minutes; in these cases, when the PC or monitor reactivates, I see the IDE flickering, and I find the toolbars messed up.

     

    To fix them, I also do right-click on the toolbars, select "customize," choose the displayed toolbars, and click the "reset" button, and almost always everything goes back to normal.

     

    With this issue, I have often found the sizes of the forms open in the IDE at that moment messed up. Now I am getting into the habit of closing the IDE when I'm not using it and if I have to step away from the PC (which is ridiculous!).

    • Like 1

  5. 768341683_F2084InternalError.thumb.png.2dbcaadda73952e2ff67bb4e7bf438ff.png

     

    With Delphi 12.1, this error has reappeared quite annoyingly... With Delphi 11.3, I had practically forgotten about it (it never happened to me). Obviously, the error is completely random and disappears when closing and reopening the IDE. But is there no way to get more information from the compiler about the error to understand if it's possible to do something to prevent it? However, it always occurs in the context of a global recompilation of a project group that contains both runtime packages, DLLs, and executables.


  6. 6 hours ago, Dave Nottage said:

    The biggest problem is when you create descendant forms (i.e. at design-time) where the ancestor contains frames. Otherwise, for me they're totally fine.

    Yes I totally agree I'm using frames in my projects sometimes in descendant forms and this is the biggest problem I have encountered. Especially in managing events on descendant frame components that often become disconnected. At some point I started managing and connecting them at runtime.

    • Like 1

  7. Hi, I'm using D11.3 on HIDPI monitor 3840x2160 with 200% zoom (Windows 11).

     

    I've just updated GExpert to latest r4210 and now I'm experiencing some annoying problems realated to hidpi:

    • "Procedure List" is unusable: the form is opened incredibly big it is even larger than the screen and only the first column with a very large font is visible. The only way to move is to press alt-space
    • The "Grep Results" window is a mess: has some parts very small, some big same normal..

     

    Grep Results:

    1642892848_GrepResults.thumb.png.c23c75301cd03802931d9cdc968ae1c1.png

     

    Procedure List

    979256734_procedurelist.thumb.png.432b6940b12c47818532916e4efed5bf.png


  8. I don't know if this can help and perhaps you have already done this, but according to FB4 documentation, to use embedded version to connect to one database from several applications, you need to set the parameter "ServerMode" as "Classic" in firebird.conf (this was the default behaviour of FB2.5 embedded now changed in FB4 in "Super").

     

    https://ib-aid.com/download/docs/fb4migrationguide.html (read section "1.5 Installing Embedded")

     

    firebird.conf comments:

    # ============================
    # Settings for Architecture Configuration
    # ============================
    
    #
    # Controls the method Firebird engine uses to work with databases and
    # related Firebird server startup parameters.
    #
    # The values are:
    # Super / ThreadedDedicated - databases are opened exclusive by single server process,
    #	attachments share single DB pages cache inside process
    # SuperClassic / ThreadedShared - databases are opened by single server process,
    #	but it does not prevent opening them in other processes (embedded access),
    #	each attachment has its own DB pages cache
    # Classic / MultiProcess - for each attachment to server a separate process is started,
    #	each database may be opened by multiple processes (including local ones for
    #	embedded access), each attachment (process) has its own DB pages cache
    #
    # Type: string
    #
    #ServerMode = Super
    

     

     

     

    • Like 1

  9. I spent some time to deep analize the MadExcept callstack and I discovered that the thread in exception was created by another thread not even executing (I can't find his "father" in the thread list reported by madExcept).

    Now I've rearranged same things in the steps involved in the app terminating phase to avoid this; I've also moved the IOmniTimedTask instance as a global variable to avoid strange dependencies. Now I cannot reproduce the error.

     

    So OTL seems working fine as usual!  It's always a mess working with threads!


  10. 1 hour ago, Lars Fosdal said:

    Does this trick have any effect?

    I abandoned that trail: the problem is not the REST call. I've substituted it with a sleep(1000) and I get the same random error... The problem is somewhere else. Still investigating...


  11. 28 minutes ago, Davide Angeli said:

    I don't know how the WiRL client works at a low level. Now I'll delve deeper.

    WiRL client seems using THTTPClient.Get and then THTTPClient.DoExecute to execute my REST operation (a PATCH). So I suppose that it is synchronous.


  12. 35 minutes ago, Lars Fosdal said:

    If a REST call is in progress when you terminate - will the code hangup and close the REST related thread(s) ?

    I rely on the fact that by calling the stop method it waits and completes any ongoing operations. When the application ends, each TimedTask is stopped and its end is awaited. But in fact, if the REST execution is asynchronous, this might still be running. I don't know how the WiRL client works at a low level. Now I'll delve deeper.


  13. 2 hours ago, Tommi Prami said:

    Could you run  the app in debugger and put break points at the end of DoSometing1 and DoSometing2, and be sure that you exit from them cleanly?

    It's not so easy to debug this;  when I debug and put breakpoints inside threads, thanking our beloved IDE, I get often debugger freezes. 

     

    In my case "DoSomething" code is a simple rest call (I use WiRL client to send data to WiRL server); the rest call is incapsulated in a try except to avoid errors.

     

    Til now my "DoSomething" was an anonymous method. Now I've changed my code and I pass a normal procedure to timedtask.execute. Things seem to going better but I don't think this was the cause of the error.

×