Compartir a través de


Creación de un comando APDU ISO7816-4

Para agregar funcionalidad a un proveedor de servicios, debe saber cómo se compila una unidad de datos del protocolo de aplicación ISO7816-4 (APDU) dentro de los archivos DLL del proveedor de servicios base. El siguiente procedimiento proporciona una breve introducción al proceso de compilación.

Nota

El ejemplo incluido aquí no es necesariamente completo; para obtener más información, consulte las aplicaciones de ejemplo y los archivos DLL.

 

Para compilar un comando APDU ISO7816-4

  1. Cree un objeto ISCardCmd y un objeto 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);
    

    La interfaz ISCardCmd contiene dos búferes IByteBuffer . Un búfer contiene la cadena de comandos APDU real (además de los datos que se van a enviar con el comando). El otro contiene cualquier información de respuesta devuelta por la tarjeta después de la ejecución del comando.

  2. Con estos objetos, cree un comando ISO7816-4 válido de la siguiente manera:

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

    Este es el código usado en el método 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);
        }
    }
    

    El método ISCardISO7816::GetChallenge usa el método ISCardCmd::BuildCmd para compilar la APDU solicitada. Para ello, escriba la información adecuada en el búfer DE APDU ISCardCmd en la siguiente instrucción:

    hr = (*ppCmd)->BuildCmd;
    
  3. Con el objeto ISCardCmd compilado , realice una transacción con la tarjeta, interprete los resultados y continúe.

Expandir más allá de ISO7816-4

La manera recomendada de expandir el proceso de compilación o ejecución del proveedor de servicios descrito anteriormente es crear un nuevo objeto COM. Este objeto COM debe admitir una nueva interfaz que permita la creación de comandos que no son ISO7816-4 y debe agregar la interfaz ISCardISO7816 .

Ejemplo de creación de un comando APDU ISO7816-4

En el ejemplo siguiente se muestra el código usado en el procedimiento anterior.

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