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
User avatar
XeviCOMAS
Posts: 486
Joined: Sat Mar 12, 2011 8:16 pm

Almacen de Firmas

Postby XeviCOMAS » Wed Jan 16, 2019 6:52 pm

¿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...

Code: Select all

#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.
User avatar
XeviCOMAS
Posts: 486
Joined: Sat Mar 12, 2011 8:16 pm

Re: Almacen de Firmas

Postby XeviCOMAS » Mon Jan 21, 2019 10:45 am

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.



Code: Select all

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.
User avatar
bingen
Posts: 372
Joined: Mon Jul 07, 2014 8:17 pm
Location: Bilbao
Contact:

Re: Almacen de Firmas

Postby bingen » Thu Jan 24, 2019 8:52 pm

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

Return to “Spanish”