In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Almacen de Firmas

Foro público de Xailer en español
Responder
Avatar de Usuario
XeviCOMAS
Mensajes: 586
Registrado: Sab Mar 12, 2011 8:16 pm

Almacen de Firmas

Mensaje por XeviCOMAS »

¿Cómo se puede abrir el diálogo/ventana de certificados de firmas para seleccionar de entre ellas???

He encontrado una función Wrapper, pero no se como portar para utilizarla en Xailer...

Código: Seleccionar todo

#pragma BEGINDUMP

#include <windows.h>
#include <psapi.h>
#include <hbapi.h>
#include <hbapierr.h>
#include <hbapiitm.h>
#include <wincrypt.h>

#define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010

//Definir el prototipo de las funciones:
typedef HCERTSTORE (WINAPI * PTYPECERTOPEN) (HCRYPTPROV, LPTSTR);
typedef PCCERT_CONTEXT (WINAPI * PTYPECERTSELECTDLG) (HCERTSTORE, HWND, LPCWSTR, LPCWSTR, DWORD, DWORD, void*);
typedef PCCERT_CONTEXT (WINAPI * PTYPECERTENUM) (HCERTSTORE, PCCERT_CONTEXT);
typedef DWORD (WINAPI * PTYPECERTGETNAME) (PCCERT_CONTEXT, DWORD, DWORD, VOID*, LPTSTR, DWORD);
typedef DWORD (WINAPI * PTYPECERTNAMETOSTR) (DWORD, PCERT_NAME_BLOB, DWORD, LPTSTR, DWORD);
typedef BOOL (WINAPI * PTYPECERTFREECC) (PCCERT_CONTEXT);
typedef BOOL (WINAPI * PTYPECERTCLOSESTORE) (HCERTSTORE, DWORD);

HB_FUNC(SELCERT)
{

   // Hay varios ejemplos en: https://msdn.microsoft.com/en-us/librar ... 61(v=vs.85).aspx

   HCERTSTORE hStore;
   PCCERT_CONTEXT PrevContext, CurContext;
   PCHAR sNombre;
   DWORD cbSize;
   PHB_ITEM pArray;
   PHB_ITEM pItem;
   PCCERT_CONTEXT   pCertContext;
   // Cargamos las librerías de las que queremos la dirección de las funciones.
   HMODULE HCrypt = LoadLibrary("Crypt32.dll");
   HMODULE HCrypt2 = LoadLibrary("Cryptui.dll");

   // Declaramos el tipo de puntero a la función, tenemos la definición arriba.
   PTYPECERTOPEN    pCertOpen;
   PTYPECERTSELECTDLG    pCertSelectDlg;
   PTYPECERTGETNAME pCertGetName;
   PTYPECERTNAMETOSTR pCertNameToStr;
   PTYPECERTFREECC pCertFreeCC;
   PTYPECERTCLOSESTORE pCertCloseStore;


   if (HCrypt != NULL && HCrypt2 != NULL){
      //Sacamos el puntero todas las funciones que vamos a usar mediante GetProcAddress:
      #ifdef UNICODE
         pCertOpen    = (PTYPECERTOPEN) GetProcAddress(HCrypt, "CertOpenSystemStoreW");
         pCertGetName = (PTYPECERTGETNAME) GetProcAddress(HCrypt, "CertGetNameStringW");
      #else
         pCertOpen    = (PTYPECERTOPEN) GetProcAddress(HCrypt, "CertOpenSystemStoreA");
         pCertGetName = (PTYPECERTGETNAME) GetProcAddress(HCrypt, "CertGetNameStringA");
      #endif
      pCertSelectDlg = (PTYPECERTSELECTDLG) GetProcAddress(HCrypt2, "CryptUIDlgSelectCertificateFromStore");
      pCertFreeCC  = (PTYPECERTFREECC) GetProcAddress(HCrypt, "CertFreeCertificateContext");
      pCertCloseStore  = (PTYPECERTCLOSESTORE) GetProcAddress(HCrypt, "CertCloseStore");
   }

   if (pCertOpen){
      // Llamada a CertOpenSystemStore:
      hStore = pCertOpen(NULL, TEXT("MY"));
   }

   if (hStore){
      // Diálogo de selección de certificado:
      pCertContext = pCertSelectDlg(hStore, NULL, NULL, NULL, CRYPTUI_SELECT_LOCATION_COLUMN, 0, NULL);

      if (pCertContext){
         cbSize = pCertGetName(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
         if (cbSize>0) {
            //Reservamos la memoria que necesitamos para el texto que recibiremos
            sNombre = (LPTSTR)malloc(cbSize * sizeof(TCHAR));

            pCertGetName(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, sNombre, cbSize);

            // Llamada a CertFreeCertificateContext:
            pCertFreeCC(pCertContext);
         }
      }

      // Cerrar el almacen de certificados:
      // Llamada a CertCloseStore:
      pCertCloseStore(hStore, 0);
    }

    FreeLibrary(HCrypt);
    FreeLibrary(HCrypt2);

    hb_retc(sNombre);

}

#pragma ENDDUMP
Alguien que lo esté utilizando o accediendo desde Xailer???
Alguien que pueda portar ese Wrapper a Xailer???

Gracias por vuestro tiempo.
Un Saludo,
Xevi.
Avatar de Usuario
XeviCOMAS
Mensajes: 586
Registrado: Sab Mar 12, 2011 8:16 pm

Re: Almacen de Firmas

Mensaje por XeviCOMAS »

Bien, de momento lo he arreglado creando un ejecutable con otra herramienta, y la llamo desde mi aplicación Xailer.
Esta miniaplicación.exe abre el almacén de firmas, selecciono el certificado, y guardo en un fichero temporal el "nombre" del certificado seleccionado, que és el que utilizaré mas adelante en mi aplicación.
No es lo más correcto, seguro, pero funciona y así lo puedo tener integrado TODOenUNO en mi aplicación.


Código: Seleccionar todo

METHOD EditCertificatBtnClick( oSender, Value ) CLASS TFrmFacturae

   Execute( AppData:cRuta+"SelCertif.exe", AppData:cRuta, .T., SW_HIDE )
   ::oEditCertificat:cText := MemoRead( "SelCertif" )
   FErase( "SelCertif" )
   IF( Len(::oEditCertificat:cText) < 15, ::oEditCertificat:cText := "", )
   ::oBtnFirma:lEnabled := !Empty(::oEditCertificat:cText)

RETURN Nil
Un Saludo,
Xevi.
Avatar de Usuario
bingen
Mensajes: 565
Registrado: Lun Jul 07, 2014 8:17 pm
Ubicación: Bilbao
Contactar:

Re: Almacen de Firmas

Mensaje por bingen »

Que buena noticia, nos va a hacer falta en breve seguro y no sabía como afrontarlo.

Muchas gracias.
BiSoft Desarrollo de software profesional
http://www.bisoft.es
Responder