Carlos,
Comparto por aqui la clase para AutofirmaCommandLine.exe
Con respecto a la clase puente me es imposible ahora mismo, requiere mucho trabajo de limpieza y aclaracion: Repasandola he visto que hice tambien una clase Tree dummy para simular un Tree que utilizó Manuel Calero con la clase de la Factura-e.
Code: Select all | Expand
//-------------------------------------------------------------------------//
FUNCTION Test_Autofirma()
Local oAutoFirma
Local cCerFile:= "Algo.pfx"
Local lFormatoFacturaE:= .t.
Local cIn:= "FacE.xml"
Local cOut:= "FacE.xSig"
Local lFirmadaOk
oAutoFirma:= TAutoFirmaDigital():New(lFormatoFacturaE)
oAutoFirma:cCerAlias:= "xx-8d6560e6-0cfc-4ebd-b165-xxxxxxxxxxxx"
oAutoFirma:cCerPass := "CONTRASEÑA" // Password del certificado
oAutoFirma:cCerFile := '"'+ PWPATH_PROGRAM+ '\Firma\Certificados\'+ cCerFile+ '"'
oAutoFirma:Activate()
lFirmadaOk:= oAutoFirma:lFirma(cIn, cOut)
return nil
*
//-------------------------------------------------------------------------//
// clase para utilizar AutoFirma.exe (El instalador
// autofirma.exe genera al instalarse
// \archivos de programa\autofirma\autofirma\autofirma.exe )
// Descargado desde http://administracionelectronica.gob.es/ctt/clienteafirma
CLASS TAutoFirmaDigital // Tags: CLASS TAutoFirma / CLASS TFirmaDigital
METHOD New()
METHOD lEstaInstalado()
METHOD Activate()
METHOD lFirma(cIn, cOut)
DATA cCerFile
DATA cCerPass
DATA cCerAlias
DATA cFullFileXml
DATA cFullFileSig // Opcional. Despues de firmar tendra el nombre del archivo con firma
DATA cFullAutoFirmaExe READONLY //INIT cFULL_AUTOFIRMA
METHOD Debug()
DATA lFormatoFacturaE READONLY
*
ENDCLASS
*
//-------------------------------------------------------------------------//
METHOD New(lFormatoFacturaE) CLASS TAutoFirmaDigital
DEFAULT lFormatoFacturaE:= .t.
::lFormatoFacturaE:= lFormatoFacturaE
*
IF ::lFormatoFacturaE
::cFullAutoFirmaExe:= "Firma\autofirma.exe"
ELSE
::cFullAutoFirmaExe:= "c:\Program Files\AutoFirma\AutoFirma\AutoFirmaCommandLine.exe"
ENDIF
RETURN Self
//-------------------------------------------------------------------------//
METHOD lEstaInstalado() CLASS TAutoFirmaDigital
RETURN File(::cFullAutoFirmaExe)
*
//-------------------------------------------------------------------------//
METHOD Activate() CLASS TAutoFirmaDigital
IF ::cFullFileXml != NIL // Permitido NIL y asi se deben pasar como parametros en :lFirma()
IF ::cFullFileSig == NIL
::cFullFileSig:= FileNueExtension(::cFullFileXml, ".xSig")
ENDIF
ENDIF
RETURN Self
*
//-------------------------------------------------------------------------//
METHOD lFirma(cIn, cOut) CLASS TAutoFirmaDigital
Local cComando, cComandoRun
Local lFirmado
Local lFile, lGeneradoCorrecto
Local nSecIni, nSecEspera
Local cFullAutoFirmaExe:= ::cFullAutoFirmaExe
Local cCerAliasTmp
Local cHashPolitica, cConfigPolitica
*
DEFAULT cIn := ::cFullFileXml
IF cOut == NIL
cOut:= ::cFullFileSig
ELSE
::cFullFileSig:= cOut
ENDIF
*
IF !File(cFullAutoFirmaExe)
// MERROR_("Falta firmador !!", cFullAutoFirmaExe, cIn, cOut)
MsgInfo("FAlta firmador !!", cFullAutoFirmaExe)
RETURN .F.
ENDIF
*
IF Empty(::cCerFile) .OR.;
Empty(::cCerAlias) .OR. Empty(::cCerPass)
*
// FLOGMSG_("Faltan datos para firmador !!", ::cCerFile, ::cCerAlias, ::cCerPass)
// MERROR_( "Faltan datos para firmador !!", ::cCerFile, ::cCerAlias) //, ::cCerPass)
RETURN .F.
ENDIF
*
#Define TAG_OCULTA_PASS "__PASS__"
#Define SPA_ Space(1)
*
cCerAliasTmp:= '"'+ ::cCerAlias+ '"'
*
cComando:= '"'+ cFullAutoFirmaExe+ '"'+ SPA_+;
;
; // Comando firmar
"sign"+ Space(1)+;
;
; // Opciones
"-store pkcs12:"+ ::cCerFile+ SPA_+;
"-password" + SPA_+ TAG_OCULTA_PASS+ SPA_+;
"-alias" + SPA_+ cCerAliasTmp+ SPA_+;
"-i" + SPA_+ cIn+ SPA_+;
"-o" + SPA_+ cOut
IF ::lFormatoFacturaE
// Formato: Factura Electronica
cComando+= SPA_+ "-format" + SPA_+ "facturae"
ELSE
// Formato: Xades / Ticket Bai
cComando+= SPA_+ "-format" + SPA_+ "xades"
cComando+= SPA_+ "-xml"
*
// Politica de firma para Guipuzcoa / Gipuzkoa
cConfigPolitica:=;
'-config "format=XAdES Enveloped '+;
'\npolicyIdentifier=https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf '+;
'\npolicyIdentifierHash=%HASH_POLITICA% '+;
'\npolicyIdentifierHashAlgorithm=http://www.w3.org/2001/04/xmlenc#sha256 '+;
'\npolicyQualifier=https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf"'
cHashPolitica:= "Quzn98x3PMbSHwbUzaj5f5KOpiH0u8bvmwbbbNkO9Es="
cConfigPolitica:= StrTran(cConfigPolitica, "%HASH_POLITICA%", cHashPolitica)
*
cComando+= SPA_+ cConfigPolitica
ENDIF
IF File(cOut)
DELETE FILE (cOut)
ENDIF
*
//FLOGMSG_("Antes de firmar 1", cComando)
*
#define SW_HIDE 0
cComandoRun:= StrTran(cComando, TAG_OCULTA_PASS, ::cCerPass) // Para que no se grabe
*
WaitRun(cComandoRun, SW_HIDE)
*
nSecIni := Seconds()
nSecEspera:= 10 // Espera maxima por cada fra (10 segundos)
DO WHILE !File(cOut) .AND. Seconds() < nSecIni+ nSecEspera // Solo tiempo para que si da error y
ENDDO // por tanto no genera el .xsig, no se quede colgado
*
// El .xsig se puede generar con mensajes de error (en su interior)...
// asi que para saber si se genero bien, se busca cualquier palabra
// clave del xml
#Define PALABRA_CLAVE_CUALQUIERA_FORMATO_FACTURAE "<BuyerParty>"
#Define PALABRA_CLAVE_CUALQUIERA_FORMATO_TICKETBAI "SignatureValue>"
#Define PALABRA_CLAVE_CUALQUIERA If(::lFormatoFacturaE,;
PALABRA_CLAVE_CUALQUIERA_FORMATO_FACTURAE,;
PALABRA_CLAVE_CUALQUIERA_FORMATO_TICKETBAI)
#Define lGENERADO_XSIG_CORRECTO ;
At(PALABRA_CLAVE_CUALQUIERA, MemoRead(cOut) ) > 0
lFile:= File(cOut)
IF lFile
lGeneradoCorrecto:= lGENERADO_XSIG_CORRECTO
lFirmado:= lGeneradoCorrecto
ELSE
lFirmado:= .f.
ENDIF
*
//FLOGMSG_("Despues de firmar", cComando, lFirmado, lFile, lGeneradoCorrecto, cOut)
*
RETURN lFirmado
*
//-------------------------------------------------------------------------//
METHOD Debug(nMargen) CLASS TAutoFirmaDigital
Local nI
Local cDebug:= ""
Local aDat:= {}
*
Aadd(aDat, {"cCerFile" , ::cCerFile } )
Aadd(aDat, {"cFullFileXml" , ::cFullFileXml } )
Aadd(aDat, {"cFullFileSig" , ::cFullFileSig } )
Aadd(aDat, {"cCerAlias" , ::cCerAlias } )
Aadd(aDat, {"cFullAutoFirmaExe", ::cFullAutoFirmaExe } )
Aadd(aDat, {"lEstaInstalado", ::lEstaInstalado} )
*
IF nMargen == NIL
nMargen:= 0
ENDIF
FOR nI:= 1 TO Len(aDat)
cDebug+= Space(nMargen)
cDebug+= PadR(aDat[nI, 1], 15)+ Space(1)+;
cGetInfo(aDat[nI, 2])
IF nI != Len(aDat)
cDebug+= CRLF
ENDIF
NEXT
RETURN cDebug
*
Salu2