Erstellen eines ISO7816-4-APDU-Befehls

Um einem Dienstanbieter Funktionen hinzuzufügen, müssen Sie wissen, wie eine ISO7816-4-Anwendungsprotokoll-Dateneinheit (APPLICATION Protocol Data Unit, APDU) in den BASIS-Dienstanbieter-DLLs erstellt wird. Das folgende Verfahren bietet eine kurze Übersicht über den Buildprozess.

Hinweis

Das hier enthaltene Beispiel ist nicht unbedingt vollständig. Weitere Informationen finden Sie in den Beispielanwendungen und DLLs.

So erstellen Sie einen ISO7816-4-APDU-Befehl

  1. Erstellen Sie ein ISCardCmd-Objekt und ein ISCardISO7816-Objekt.

    //  Create an ISCardCmd object.
    HRESULT hresult = CoCreateInstance(CLSID_CSCardCmd,
                               NULL,
                               CLSCTX_ALL,
                               IID_ISCardCmd,
                               (LPVOID*) &g_pISCardCmd);
    //  Create an ISCardISO7816 object.
    HRESULT hresult = CoCreateInstance(CLSID_CSCardISO7816,
                               NULL,
                               CLSCTX_ALL,
                               IID_ISCardISO7816,
                               (LPVOID*) &g_pISCardISO7816);
    

    Die ISCardCmd-Schnittstelle enthält zwei IByteBuffer-Puffer. Ein Puffer enthält die tatsächliche APDU-Befehlszeichenfolge (sowie alle Daten, die mit dem Befehl gesendet werden sollen). Die andere enthält alle Antwortinformationen, die von der Karte nach der Befehlsausführung zurückgegeben werden.

  2. Erstellen Sie mit diesen Objekten einen gültigen ISO7816-4-Befehl wie folgt:

    //  Do challenge.
    HRESULT hresult = g_pISCardISO7816->GetChallenge(dwLengthOfChallenge,
                                             &g_pISCardCmd);
    

    Hier ist der Code, der in der GetChallenge-Methode verwendet wird:

    #include <windows.h>
    
    STDMETHODIMP CSCardISO7816::GetChallenge(IN DWORD dwBytesExpected /*= 0*/,
                                IN OUT LPSCARDCMD *ppCmd)
    {
        //  Locals.
        HRESULT hr = S_OK;
    
        try
        {
            //  Is the ISCardCmd object okay?
            hr = IsSCardCmdValid(ppCmd);
            if (FAILED(hr))
                throw (hr);
    
            //  Do it.
            hr = (*ppCmd)->BuildCmd(m_byClassId,
                                    (BYTE) INS_GET_CHALLENGE,
                                    (BYTE) INS_NULL,  // P1 = 0x00
                                    (BYTE) INS_NULL,  // P2 = 0x00
                                    NULL,
                                    &dwBytesExpected);
            if (FAILED(hr))
                throw (hr);
        }
    }
    

    Die ISCardISO7816::GetChallenge-Methode verwendet die ISCardCmd::BuildCmd-Methode, um die angeforderte APDU zu erstellen. Hierzu werden die entsprechenden Informationen in den ISCardCmd-APDU-Puffer in der folgenden Anweisung geschrieben:

    hr = (*ppCmd)->BuildCmd;
    
  3. Mithilfe des erstellten ISCardCmd-Objekts können Sie eine Transaktion mit der Karte durchführen, die Ergebnisse interpretieren und fortfahren.

Erweiterung über ISO7816-4 hinaus

Die empfohlene Methode zum Erweitern des oben beschriebenen Build-/Ausführungsprozesses des Dienstanbieters besteht darin, ein neues COM-Objekt zu erstellen. Dieses COM-Objekt sollte eine neue Schnittstelle unterstützen, die die Erstellung von Nicht-ISO7816-4-Befehlen ermöglicht, und die ISCardISO7816-Schnittstelle aggregieren.

Beispiel für das Erstellen eines ISO7816-4-APDU-Befehls

Das folgende Beispiel zeigt den Code, der in der obigen Prozedur verwendet wird.

//  Create an ISCardCmd object.
hresult = CoCreateInstance(CLSID_CSCardCmd,
                           NULL,
                           CLSCTX_ALL,
                           IID_ISCardCmd,
                           (LPVOID*) &g_pISCardCmd);
//  Create an ISCardISO7816 object.
hresult = CoCreateInstance(CLSID_CSCardISO7816,
                           NULL,
                           CLSCTX_ALL,
                           IID_ISCardISO7816,
                           (LPVOID*) &g_pISCardISO7816);
//  Do challenge.
hresult = g_pISCardISO7816->GetChallenge(dwLengthOfChallenge,
                                         &g_pISCardCmd);

STDMETHODIMP
CSCardISO7816::GetChallenge(IN DWORD dwBytesExpected /*= 0*/,
                            IN OUT LPSCARDCMD *ppCmd)
{
    //  Locals.
    HRESULT hr = S_OK;
    
    try
    {
        //  Is the ISCardCmd object okay?
        hr = IsSCardCmdValid(ppCmd);
        if (FAILED(hr))
            throw (hr);

        //  Do it.
        hr = (*ppCmd)->BuildCmd(m_byClassId,
                                (BYTE) INS_GET_CHALLENGE,
                                (BYTE) INS_NULL,  // P1 = 0x00
                                (BYTE) INS_NULL,  // P2 = 0x00
                                NULL,
                                &dwBytesExpected);
        if (FAILED(hr))
            throw (hr);
    }
}