Página 1 de 1

Almacen de Firmas

Publicado: Mié Ene 16, 2019 6:52 pm
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.

Re: Almacen de Firmas

Publicado: Lun Ene 21, 2019 10:45 am
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

Re: Almacen de Firmas

Publicado: Jue Ene 24, 2019 8:52 pm
por bingen
Que buena noticia, nos va a hacer falta en breve seguro y no sabía como afrontarlo.

Muchas gracias.