Condividi tramite


Creazione di un comando APDU ISO7816-4

Per aggiungere funzionalità a un provider di servizi, è necessario conoscere il modo in cui un'unità dati del protocollo applicazione ISO7816-4 (APDU) viene costruita all'interno delle DLL del provider di servizi di base. La procedura seguente offre una breve panoramica del processo di compilazione.

Nota

L'esempio qui incluso non è necessariamente completo; Per altre informazioni, vedere le applicazioni e le DLL di esempio.

 

Per compilare un comando APDU ISO7816-4

  1. Creare un oggetto ISCardCmd e un oggetto ISCardISO7816.

    //  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);
    

    L'interfaccia ISCardCmd contiene due buffer IByteBuffer. Un buffer contiene la stringa di comando APDU effettiva (più i dati da inviare con il comando). L'altro contiene le informazioni di risposta restituite dalla scheda dopo l'esecuzione del comando.

  2. Usando questi oggetti, creare un comando ISO7816-4 valido come indicato di seguito:

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

    Di seguito è riportato il codice usato nel metodo GetChallenge:

    #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);
        }
    }
    

    Il metodo ISCardISO7816::GetChallenge usa il metodo ISCardCmd::BuildCmd per compilare l'APDU richiesto. A tale scopo, scrivere le informazioni appropriate nel buffer ISCardCmd APDU nell'istruzione seguente:

    hr = (*ppCmd)->BuildCmd;
    
  3. Utilizzare l'oggetto costruito ISCardCmd, eseguire una transazione con la carta, interpretare i risultati e continuare.

Espandere oltre l'ISO7816-4

Il modo consigliato per espandere il processo di compilazione/esecuzione del provider di servizi descritto in precedenza consiste nel creare un nuovo oggetto COM. Questo oggetto COM deve supportare una nuova interfaccia che consente la creazione di comandi non ISO7816-4 e deve aggregare l'interfaccia ISCardISO7816.

Esempio di compilazione di un comando APDU ISO7816-4

Nell'esempio seguente viene illustrato il codice usato nella procedura precedente.

//  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);
    }
}