Jump to content

Davide Angeli

  • Content Count

  • Joined

  • Last visited

  • Days Won


Davide Angeli last won the day on July 8 2021

Davide Angeli had the most liked content!

Community Reputation

32 Excellent

About Davide Angeli

  • Birthday 11/24/1971

Technical Information

  • Delphi-Version
    Delphi 11 Alexandria

Recent Profile Visitors

727 profile views
  1. Davide Angeli

    Black Firiday Discounts for Almediadev products!

    too many "w" in links 😊
  2. Davide Angeli

    Delphi 12 is available

    On QP is set as resolved in D12.... https://quality.embarcadero.com/browse/RSP-42024
  3. Davide Angeli

    Importing WSDL

    Maybe the problem could be that the WSDL contains an xsl stylesheet. Have you tried downloading the wsdl source to a disk file and then importing into Delphi from that local file?
  4. I solved this thanks to the kind collaboration of the nSoftware assistance service (SecureBlackBox's developer). There were many challenges to solve to achieve the goal and very little can be found online. It is my understanding that this type of security is not used much in the Delphi environment. However I solved by combining several components provided with the SecurityBlackBox suite: TsbxCertificateStorage to read JKS file to reach public key (used to encrypt the request and verify the signed response) and private key (used to sign the request and decrypt the response) TsbxSOAPSigner to sign the SOAP request (to produce a WSSSignature) TsbxXMLEncryptor to embed in the request the encryption key (transported with RSA-OAEP sha1) and to crypt the SOAP request body (with AES128 algorithm) TsbxXMLDecryptor to decrypt the response (two items encrypted in the response: the sign and the body) TsbxSOAPVerifier to verifiy the sign in the response I've injected this encryption/decryption stuff in THTTPRio events, somthing like this; procedure TMultyAssociativeServiceWrapper.SOAPOnBeforeExecute(const MethodName: String; SOAPRequest: TStream); begin // save the original request (created by THTTPRio) for debug purpose SOAPRequest.Seek(0,0); (SOAPRequest as TMemoryStream).SaveToFile(FFileRequestOriginal); // sign and encrypt the original request SBBSoapSignAndEncryptWithJKS(FFileRequestOriginal, FFileRequestToSend, FCertificateFileJKS, OnPasswordNeeded); // ... do some other stuff ? // update the outcoming request with the signed crypted version SOAPRequest.Seek(0,0); (SOAPRequest as TMemoryStream).LoadFromFile(FFileRequestToSend); end; procedure TMultyAssociativeServiceWrapper.SOAPOnAfterExecute(const MethodName: String; SOAPResponse: TStream); begin // save te orginal response arrived from service for debug purpose SOAPResponse.Seek(0,0); (SOAPResponse as TMemoryStream).SaveToFile(FFileResponseOriginal); // decrypt and verify sign of response SBBSoapDecryptAndVerifyWithJKS(FFileResponseOriginal, FFileResponseDecoded, FCertificateFileJKS, OnPasswordNeeded); //... do some other stuff? // update the incoming response with the decrypted data SOAPResponse.Seek(0,0); (SOAPResponse as TMemoryStream).LoadFromFile(FFileResponseDecoded); end; SBBSoapSignAndEncryptWithJKS does sign + encryption stuff. SBBSoapDecryptAndVerifyWithJKS does decrypt and verify sign stuff. I hope this can be helpful for someone else who runs into this need. If you need the code of the two SBB procedures described above please ask me. I've used SecureBlackBox components but I think that same stuff could be reached also with ChilKat library. I did some tests with the demo library, it works at a lower level of SBB but there are several examples online that could be combined to reach the goal.
  5. Yes, with SBB is not possibile to reach the same request without doing some further manipulation of the xml and it misses also the reference list for decryption. I'm working on that and another problem I think should be the order of doing operations: I'm doing crypt+sign but I'm investigating if service aspect sign and then crypt. I will do theese changes but I could not test because of server down for maintenance. I'll report the results.
  6. Hi all, I'm really becaming crazy trying to do this with Delphi... I've to interact with a SOAP service that implements WSS security with X.509 certificate so: they give me the WSDL file they give me a Java Keystore (jks file) containg a certificate, a public key and a private key password protected the SOAP request must be signed and crypted with the jks data the SOAP response must be decrypted and signed verified a request like this one: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fut="....." xmlns:ass="...." xmlns:com="...."> <soapenv:Header/> <soapenv:Body> <fut:FutureConvocationsRequest> <associativeServicesGenericRequest> <ass:locale> <com:language>it</com:language> <com:country>IT</com:country> </ass:locale> <ass:consumer>Me</ass:consumer> <ass:associationCode>aaaa</ass:associationCode> <ass:sectionCode>bbbbb</ass:sectionCode> <ass:startDate></ass:startDate> <ass:endDate></ass:endDate> </associativeServicesGenericRequest> </fut:FutureConvocationsRequest> </soapenv:Body> </soapenv:Envelope> must become like this one (grabbed it from SoapUI logs that interact well with this service): <soapenv:Envelope xmlns:ass="..." xmlns:com="..." xmlns:fut="..." xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <xenc:EncryptedKey Id="EK-6085B5AE3B1746C574167481306190992" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <wsse:SecurityTokenReference> <ds:X509Data> <ds:X509IssuerSerial> <ds:X509IssuerName>....</ds:X509IssuerName> <ds:X509SerialNumber>....</ds:X509SerialNumber> </ds:X509IssuerSerial> </ds:X509Data> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>....</xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#ED-6085B5AE3B1746C574167481306190993"/> </xenc:ReferenceList> </xenc:EncryptedKey> <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="X509-6085B5AE3B1746C574167481306190587">....</wsse:BinarySecurityToken> <wsu:Timestamp wsu:Id="TS-6085B5AE3B1746C574167481306190486"> <wsu:Created>2023-01-27T09:51:01Z</wsu:Created> <wsu:Expires>2023-01-27T09:56:01Z</wsu:Expires> </wsu:Timestamp> <ds:Signature Id="SIG-6085B5AE3B1746C574167481306190591" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> <ec:InclusiveNamespaces PrefixList="ass com fut soapenv" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:CanonicalizationMethod> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI="#id-6085B5AE3B1746C574167481306190590"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> <ec:InclusiveNamespaces PrefixList="ass com fut" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>7APwAAzaHndcDEHSBYlA6b/rihY=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>....</ds:SignatureValue> <ds:KeyInfo Id="KI-6085B5AE3B1746C574167481306190588"> <wsse:SecurityTokenReference wsu:Id="STR-6085B5AE3B1746C574167481306190589"> <wsse:Reference URI="#X509-6085B5AE3B1746C574167481306190587" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature> </wsse:Security> </soapenv:Header> <soapenv:Body wsu:Id="id-6085B5AE3B1746C574167481306190590" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <xenc:EncryptedData Id="ED-6085B5AE3B1746C574167481306190993" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <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="#EK-6085B5AE3B1746C574167481306190992"/> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>....</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </soapenv:Body> </soapenv:Envelope> I've used several SOAP service but never with this kind of security so til now I've always used default THTTPRio with WSDL importer. I don't know if in this case this is the best approach but I've imported the WSDL file in Delphi creating all SOAP objects to use with THTTPRIO . Then I've coded the THTTPRio.OnBeforeExecute to inject the necessary data and trasform the request as needed. I've a regular license of SecureBlackBox components so I can easily read the certificate data from Keystore and using the SOAPSigner + XMLEncryptor components (with some post processing to adjust some Secureblackbox issues), I'm capable to transform the request as needed but when I send it to the service I got always an error like "The signature or decryption was invalid" (Unfortunately I can't get quick answers from the service provider because it is a government agency and not very responsive...). I suppose that could be an encryption problem because the XML soap request just signed (not encrypted) seems ok (just tested with SecureBlackbox SOAPVerifier). If there is here some SOAP Delphi guru my questions are: - do you know if exists a good tool to verify if the request is well formed? If the encryption is well done? If the sign is correct? - SecureBlackBox suite is very complex to configure... do you know if exists some other Delphi solution to obtain the result easier?
  7. You can't destroy the thread object until it's finished... It doesn't even have time to start. Maybe you have to do something like this: var x: TMyThread; begin x := TMyThread.Create(False); try // x.Start; // if suspended... WaitForSingleObject(X.Handle, INFINITE); finally x.Free; end; end;
  8. Davide Angeli

    JSON superobject question

    I used JSON superobject for a while and it's good but in cases like this I prefer the very good Delphi NEON library so I could deserialize the JSON directly to Delphi objects. With NEON in a case like yours I could do something like this: Type TVoice = record public Engine : String; VoiceId : String; VoiceGender : String; // .. other fields end; TVoicesData = record public voices_list : TArray<TVoice>; count : Integer; end; TVoices = record public success : Boolean; data : TVoicesData; end; procedure TForm1.Button2Click(Sender: TObject); begin var sJson:= '{'+ ' "success": true,'+ ' "data": {'+ ' "voices_list": ['+ ' {'+ ' "Engine": "neural",'+ ' "VoiceId": "ai2-Stacy",'+ ' "VoiceGender": "Female",'+ ' "VoiceWebname": "Stacy",'+ ' "Country": "US",'+ ' "Language": "en-US",'+ ' "LanguageName": "English, US",'+ ' "VoiceEffects": ['+ ' ]'+ ' },'+ ' {'+ ' "Engine": "neural",'+ ' "VoiceId": "ai1-Matthew",'+ ' "VoiceGender": "Male",'+ ' "VoiceWebname": "Matthew",'+ ' "Country": "US",'+ ' "Language": "en-US",'+ ' "LanguageName": "English, US",'+ ' "VoiceEffects": ['+ ' "news"'+ ' ]'+ ' }'+ ' ],'+ ' "count": 50'+ ' }'+ '}'; var Voices:=DeserializeValueTo<TVoices>(sJson); for var Voice in Voices.data.voices_list do ListBox1.Items.Add(Voice.Engine+' - '+Voice.VoiceGender); end; function TForm1.DeserializeValueTo<T>(const aJSON : String): T; begin if FNeonConfig=Nil then FNeonConfig:=TNeonConfiguration.Default; var LJSON := TJSONObject.ParseJSONValue(aJSON); try var LReader:=TNeonDeserializerJSON.Create(FNeonConfig); try var LValue:=LReader.JSONToTValue(LJSON, TRttiUtils.Context.GetType(TypeInfo(T))); Result:=LValue.AsType<T>; finally LReader.Free; end; finally LJSON.Free; end; end;
  9. Davide Angeli

    JSON superobject question

    This should work: Obj.O['data'].I['count']
  10. Davide Angeli

    The Delphi 11.2 release thread

    In my case 10.4 was terrible, fortunately 11.2 seems working well (I'm using only VCL win32 & win64). At the moment, I've not installed the patch 1.0 because after several years of frustration I've finally a stable environment and I'm terrified of breaking it again!
  11. Davide Angeli

    The Delphi 11.2 release thread

    Oh yes, I've tried both: in 11.2 works fine, in 10.4 seems not working as aspected (in my case)
  12. Davide Angeli

    The Delphi 11.2 release thread

    LSP is the minor problem of 10.4, you can also disable it if you want. The fact of closing the IDE every 15 minutes, in my case, is due to the continuous internal errors, access violations in dcc32 and so on that were fixed in 11.2.
  13. Davide Angeli

    The Delphi 11.2 release thread

    As far as my usage context is concerned, version 11.2 is a big step up from 10.4. I'm switching from one to the other working on two different projects and 10.4 is truly absolute crap in terms of stability. 11.2 isn't perfect but it has improved a lot of things. In my case when LSP no longer works, now in 11.2 it is always a solution to switch from debug / release or from win32 / win64 (for me these workarounds don't work in 10.4 and the only solution remain close/reopen IDE). I've been using 11.2 for several weeks now and the IDE has crashed only a couple of times (a strange Access Violation and one internal error). For me it is a dream to be able to work even for 4 hours straight without crashing! When I come back to 10.4 I have to close and reopen the IDE at least once every 15 minutes and the LSP is totally unusable...
  14. Davide Angeli

    NetGroupGetUsers strange errors on Win64 on buffered reads

    No problem! Discover the cause of the acces violation could be maybe a good exercise for some Windows api guru. I've dedicated it some hours yesterday trying to change the way to declare the parameters of the api but I could not reach a solution. I've tried several combinations even going against what is stated in the api documentation. There is something strange tha I'm missing on that api because the totalentries out parameter is always a non sense value called in win64. In win32 works as apected. So maybe there is something not documented in the Windows api or maybe, as that api si considered very old, maybe the win64 part could be buggy (just a my guess) or maybe could be something wrong using it from a Delphi win64 program (I've tested it both 10.4.2 and 11.2 but the problem is the same).
  15. Davide Angeli

    NetGroupGetUsers strange errors on Win64 on buffered reads

    You are right but as you know things that work we don't touch as long as they work! Now I'll dedicate time to modernize that piece of code.