Neues Thema starten

Zertifikat der Swissbit-TSE auslesen

Hallo!


Für den DSFinV-K-Export benötigt man ja das Zertifkat der TSE (TSE_Zertifikat_I). Nun bietet das Swissbit-SDK eine Methode worm_getLogMessageCertificate() um das Zertifikat zu bekommen.


Leider ist der Aufruf so nie woanders verwendet und wir bringen es nicht hin unter c#. Wir schaffen es einfach nicht, einen bereits allokierten byte-buffer zu übergeben - sonst macht das immer das SDK.


Wir schaffen es, die länge auszulesen (out uint32 und den buffer als null übergeben) - aber den buffer dann auch befüllen, gelingt nicht.


Wäre super, wenn uns hier wer weiterhelfen könnte.

Dank im Voraus.


Hallo @Tech Nick,


so funktioniert es bei mir mit C#:


public string GetLogMessageCertificate()

        {

            //CTSS aktivieren if not active

            if (!info.IsCTSSInterfaceActive())

                worm_tse_ctss_enable(worm_context);

 

            var length = 0;

 

            //1. request -> get length

            var error = worm_getLogMessageCertificate(worm_context, IntPtr.Zero, ref length);

            if (error != WormError.WORM_ERROR_NOERROR)

            {

                throw new Exception("Failed to get log message certificate, error: " + error);

            }

            IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(byte)) * length);

 

            //2. request -> get certificate

            error = worm_getLogMessageCertificate(worm_context, p, ref length);

            if (error != WormError.WORM_ERROR_NOERROR)

            {

                throw new Exception("Failed to get log message certificate, error: " + error);

            }

            var buffer = new byte[length];

            Marshal.Copy(p, buffer, 0, length);

            Marshal.FreeHGlobal(p);

 

            return Encoding.ASCII.GetString(buffer);

        }


2 Personen gefällt dies

Meine Definition:
    <DllImport("WormAPI.dll", CallingConvention:=CallingConvention.Cdecl)>
    Private Shared Function worm_getLogMessageCertificate(ByVal worm_context As IntPtr, ByVal certificate As Byte(), ByRef certificateLength As UInt32) As Integer
    End Function


Der Funktionsaufruf:

        Dim nCertLength As UInt32 = 0
        Dim Certificat As Byte() = Nothing
        Try
            Dim result As Integer = worm_getLogMessageCertificate(Worm_context, Nothing, nCertLength)

            If result <> 0 Then Throw New Exception(cMe & "." & cM & " : (1) Fehler beim Export des Zertifikats : " & result)

            Certificat = New Byte(nCertLength - 1) {}
            result = worm_getLogMessageCertificate(Worm_context, Certificat, nCertLength)

            If result <> 0 Then Throw New Exception(cMe & "." & cM & " : (2) Fehler beim Export des Zertifikats : " & result)
        Catch ex As Exception
            Protokoll(cMe & "." & cM & " : " & ex.ToString)
        Finally
            ExportCertificate = Certificat
        End Try

Und dann noch das Schreiben des Byte-Arrays in die Textdatei.

Using stream As FileStream = New FileStream(strFileName, FileMode.OpenOrCreate, FileAccess.Write)
Dim bytes As Byte() = cSwissBit.ks_TSE.ExportCertificate()
   stream.Write(bytes, 0, bytes.Length)
End Using

Funktioniert :)
Ich habe aber sehr lange gebraucht, bis ich diese Lösung hatte.


1 Person gefällt dies

Hallo Vitalii Vasiak.


Vielen Dank für das Code Snippet. Es funktioniert so.


Der eigentliche Fehler war so klein und einfach - statt dem out für die Länge ein ref.


lg

Hallo,


Ich denke, du musst deine Variable length dann auch als unsigned int32 deklarieren!

Dim length as Unit32 = 0

Sonst passt ja deine Aufrufkonvention nicht. Ich gehe davon aus das der normale integer in VB.Net 64bittig ist.



Hallo, 

danke für die Rückmeldung ein uint32 und auch ein ulong für leider zum gleichen Ergebnis und es wird immer der Fehler 1 zurückgegeben.

Die Funktion worm_getLogMessageCertificate will bei certLength einen Zeiger auf einen UInt32!!! Keinen Uint32, du musst deinen Funktionsaufruf anpassen.


Dann ist es korrekt, einmal die Funktion aufrufen um die Länge des Zertifikats zu ermitten, dann damit dem Speicher auf das Array of AnsiChar reservieren und die Funktion noch mal mit dem Zeiger auf des ByteArray aufrufen.

VG

Danke für die Antwort, aber: In Vb.Net spielt im Gegensatz zu C# oder anderen Sprachen die Groß/Kleinschreibung im Code keinerlei Rolle. UInt32 oder Uint32 ist also das gleiche, es funktioniert leider nicht.

Ich hab aber mit keiner Silbe  geschrieben, dass du Gross/Kleinschreibung beachten sollst!

Ich hab geschrieben, dass die Funktion einen Zeiger(Pointer) auf eine UInt32 haben will und keinen UInt32 egal wie er geschrieben ist. Auch in VB wird es himmelweiter Unterschied sein, ob ein Integer oder einen Zeiger auf die Adress eines  Integer erwartet wird.

Der Pointer ist in Vb.Net ist bereits mit dem Schlüsselwort ByRef bei der Deklaration von worm_getLogMessageCertificate realisiert.

Ich würde es trotzdem so definieren:

statt ByRef certificateLength As UInt32

in ByVal certificateLength As IntPtr


und dann so aufrufen:

     Dim length As Unit32= 0
      Dim lenPtr AS IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(length))
      Dim result = worm_getLogMessageCertificate(Me.worm_context, IntPtr.Zero, lenPtr)
      length = Marshal.ReadInt32(lenPtr)
      Marshal.FreeHGlobal(ip)

Danke, es bleibt leider ohne Erfolg. Auch bei dieser Änderung bleibt es bei Fehler 1 (Invalid Parameter). 

 

>Und welche der drei TSE-Zertifikat brauch ich für DSFinV_K in Kapitel "3.2.7 Datei: Stamm_TSE " für >"TSE_ZERTIFIKAT_I /V"?


Hallo,


ist die Frage mittlerweile gelöst?

In meinen TAR Dateien sind aich 3 Zertifikate in der PEM Datei vorhanden.

Welches wird benötigt?


Danke


"Und welche der drei TSE-Zertifikat brauch ich für DSFinV_K in Kapitel "3.2.7 Datei: Stamm_TSE " für "TSE_ZERTIFIKAT_I /V"?"


Ich habe das gleiche Problem, die PEM Datei in den TAR exporten enthält 3 Zertifikate. Welche nimmst du?


VG

Matthias

Sind ein wenig weiter. Der pInvoke Call schaut folgend aus:


 private static extern int worm_getLogMessageCertificate(IntPtr context, IntPtr publicKey, out UInt32 certificateLength);


Dann erstellen wir uns einen unmanaged-point, allokieren Speicher. Rufen die Methode ein erstes Mal (mit null-pointer) auf, um die tatscähliche größe zu bekommen.


IntPtr unmanagedPointer = Marshal.AllocHGlobal(1024*1024);

worm_getLogMessageCertificate(wormContext, IntPtr.Zero, out var certificateBufferLen));


Das funkt auch soweit. Nur beim zweiten Aufruf, um das Zertifikat zu bekommen, scheiten wir dann beim auslesen. Inzwischen kommen zwar keine Fehler mehr, aber die geschriebene Datei ist in der angegeben Größe voll mit "NULLs"


worm_getLogMessageCertificate(wormContext, unmanagedPointer, out certificateBufferLen);

certificateBuffer = new byte[certificateBufferLen*1024+1];
Marshal.Copy(certificateBuffer, 0, unmanagedPointer, (int)certificateBufferLen);
System.IO.File.WriteAllBytes(@"c:\temp\tse.pem", certificateBuffer);



Anmelden oder Registrieren um einen Kommentar zu veröffentlichen