Condividi tramite


Creazione di un comando APDU ISO7816-4

Per aggiungere funzionalità a un provider di servizi, è necessario sapere come viene compilata un'unità dati APDU ( Application Protocol Data Unit ) ISO7816-4 all'interno delle DLL del provider di servizi di base. La procedura seguente offre una breve panoramica del processo di compilazione.

Nota

L'esempio incluso qui 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ù tutti i dati da inviare con il comando). L'altro contiene eventuali 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);
    

    Ecco 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 APDU ISCardCmd nell'istruzione seguente:

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

Espansione oltre 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 creazione 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);
    }
}