Page 1 of 2

Firmar fichero con certificado

PostPosted: Fri Oct 23, 2020 4:38 pm
by Baxajaun
Buenas tardes !!!

Las gracias y el reconocimiento a Diego Fazio.

cms.c

Code: Select all  Expand view
#include "hbssl.h"
#include <openssl/cms.h>

HB_FUNC( HB_CMS_SIGNFILE )
{
    // HB_SignFile( Archivo a firmar, Archivo .crt, Archivo .key, Archivo Firmado)
    BIO *in = NULL, *out = NULL, *archivo = NULL;
    CMS_ContentInfo *cms = NULL;
    X509 *x509;
    CMS_SignerInfo *si;
    EVP_PKEY *priKey;
    int flags = CMS_PARTIAL;
    OpenSSL_add_all_algorithms();
    OpenSSL_add_all_ciphers();
    //int flags = CMS_PARTIAL;

//read the .crt file
    archivo = BIO_new_file(hb_parc(2), "r");
    if (!archivo) {
        hb_retni(2); // error opening .crt file
        return;    
    }
    x509 = PEM_read_bio_X509(archivo, NULL, NULL, NULL);
    BIO_reset(archivo);
   
   
//read the .key file
    archivo = BIO_new_file(hb_parc(3), "r");
    if (!archivo) {
        hb_retni(3);  // error opening key file
        return;
    }
    priKey = PEM_read_bio_PrivateKey(archivo,NULL, NULL, NULL);
    if(!priKey) {
        hb_retni(4); //error creating PrivateKey object
        return;
    }

    if (!X509_check_private_key(x509, priKey)) {
        hb_retni(5); //the Key does not correspond to the Certificate
        return;    
    }   
   
//open file to sign
    in = BIO_new_file(hb_parc(1), "r");
    if (!in) {
        hb_retni(6); //error opening file to sign
        return;    
    }

//create cms object
    cms = CMS_sign(NULL, NULL, NULL, in, flags);
    if (!cms) {
        hb_retni(7); //error creating cms object
        return;    
    }
   
    //CMS_SignerInfo *si;
    si = CMS_add1_signer(cms, x509, priKey, EVP_sha1(), flags);
    if (!si) {
        hb_retni(8); //error asigning data to cms object
        return;    
    }

    if (!CMS_final(cms, in, NULL, flags)) {
        hb_retni(9); //error closing data structure of cms object
        return;    
    }

    
//create file signed
    out = BIO_new_file(hb_parc(4), "wb");
    if (!out) {
        hb_retni(10); //error creating out file
        return;    
    }
    BIO_reset(in);
   
   
    if (!i2d_CMS_bio_stream(out,cms, in, flags)) {//lo graba en formato DER
        hb_retni(11); //error generating final cms file
        return;    
    }
    CMS_ContentInfo_free(cms);
    X509_free(x509);
    BIO_free(in);
    BIO_free(out);
    BIO_free(archivo)
    hb_retni( 1 );
    return
}
 


cms_singfile_pfx.c

Code: Select all  Expand view
#include "hbssl.h"
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>
#include <openssl/cms.h>

HB_FUNC( HB_CMS_SIGNFILE_PFX )
{
    // HB_SignFile( Archivo a firmar, Archivo .pfx, clave, Archivo Firmado)
    BIO *in = NULL, *out = NULL;
    CMS_ContentInfo *cms = NULL;
    CMS_SignerInfo *si;
    int flags = CMS_PARTIAL;
    X509 *x509;
    EVP_PKEY *priKey;
    FILE *fp;
    PKCS12 *p12;
    STACK_OF(X509) *ca = NULL;
    OpenSSL_add_all_algorithms();
    OpenSSL_add_all_ciphers();
    //int flags = CMS_PARTIAL;

    if ((fp = fopen(hb_parc(2), "rb")) == NULL) {
        hb_retni( 2 );
        return;
    }
    p12 = d2i_PKCS12_fp(fp, NULL);
    fclose(fp);
    if (!p12) {
        hb_retni( 3 );
        return;
    }
    if (!PKCS12_parse(p12, hb_parc(3), &priKey, &x509, &ca)) {
        hb_retni( 4 );
        return;
    }
    PKCS12_free(p12);   

//abre el archivo a firmar 
    in = BIO_new_file(hb_parc(1), "r");
    if (!in) {
        hb_retni(5); //error al crear objeto in
        return;    
    }

//crea el cms
    cms = CMS_sign(NULL, NULL, NULL, in, flags);
    if (!cms) {
        hb_retni(6); //error al crear objeto cms
        return;    
    }
   
    //CMS_SignerInfo *si;
    si = CMS_add1_signer(cms, x509, priKey, EVP_sha1(), flags);
    if (!si) {
        hb_retni(8); //error al crear objeto cms
        return;    
    }

    if (!CMS_final(cms, in, NULL, flags)) {
        hb_retni(9); //error al crear objeto cms
        return;    
    }
    
   
    out = BIO_new_file(hb_parc(4), "wb");
    if (!out) {
        hb_retni(10); //error al abrir el archivo toSignFile
        return;    
    }
    BIO_reset(in);
   
   
    //if(!PEM_write_bio_CMS_stream(out,cms, in, flags)) {//lo graba en formato PEM
    //if (!SMIME_write_CMS(out, cms, in, flags)) { //lo graba en formato SMIME
    if (!i2d_CMS_bio_stream(out,cms, in, flags)) {//lo graba en formato DER
        hb_retni(11); //error al grabar el archivo toSignFile
        return;    
    }
    CMS_ContentInfo_free(cms);
    X509_free(x509);
    BIO_free(in);
    BIO_free(out);
    hb_retni( 1 );
    return
}


hbssl.hbm para la construcción de la librería hbssl

Code: Select all  Expand view
-stop{wce}

-hblib
-inc

-o${hb_targetname}
-workdir=${hb_work}/${hb_plat}/${hb_comp}/${hb_targetname}

-w3 -es2

-depkeyhead=openssl:openssl/ssl.h
-depcontrol=openssl:no{HB_BUILD_3RDEXT='no'}
-depcontrol=openssl:${HB_WITH_OPENSSL}
-depincpath=openssl:/usr/local/opt/openssl/include
-depincpath=openssl:/usr/local/opt/libressl/include
-depincpath=openssl:/usr/include
-depincpath=openssl:/usr/local/include
-depincpath=openssl:/usr/local/ssl/include
-depincpath=openssl:/boot/common/include
-depincpath=openssl:/usr/pkg/include
-depfinish=openssl

{darwin}-cflag=-DOPENSSL_NO_SHA256
{darwin}-cflag=-DOPENSSL_NO_SHA512
{darwin}-cflag=-DOPENSSL_NO_CAMELLIA
{darwin}-cflag=-DOPENSSL_NO_DGRAM
{darwin}-cflag=-DHB_OPENSSL_OLD_OSX_

# Patent expires in 2010/2011
-cflag=-DOPENSSL_NO_IDEA

# to suppress Apple's deprecation warnings that apply to
# the complete OpenSSL API, starting with OS X Lion 10.7
-cflag={allgcc&darwin}-Wno-deprecated

# For _fileno() in openssl/applink.c
-c=gnu90

hbssl.hbx

ssl_hbcon.prg

ssl_hb.c
ssl_inet.c
ssl_sock.c
bio.c
err.c
evp.c
evpciph.c
evpenc.c
evpmd.c
evppkey.c
pem.c
rand.c
ssl.c
sslciph.c
sslctx.c
sslsess.c
x509.c
cms_singfile_pfx.c
cms.c


Tip4.prg

Code: Select all  Expand view
#include "hbssl.ch"

Function main()
Local nError

/*
     RESULTADO
         1: Signing OK
         2: error opening .crt file
         3: error opening key file
         4: error creating PrivateKey object
         5: the Key does not correspond to the Certificate
         6: error opening file to sign
         7: error creating cms object
         8: error asigning data to cms object
         9: error closing data structure of cms object
        10: error creating out file
        11: error generating final cms file
*/

       
ssl_ini()
nError := HB_CMS_SignFile( "TRA.XML", "CERT.CRT", "CERT.KEY", "TRA.TMP")
if ( nError !=1 )
    MsgInfo( nError )
endif

return nil


He añadido las siguientes dlls ( OpenSSL ) a la ubicación del ejecutable:
Code: Select all  Expand view

libcrypto-1_1.dll
libssl-1_1.dll
 


y he añadido las siguientes libs de Harbour:

Code: Select all  Expand view

libcrypto-1_1.a
libssl-1_1.a
 


Y también he añadido las siguientes libs de MinGW:

Code: Select all  Expand view

LIBIPHLPAPI.A
LIBWS2_32.A
 


Se ha comprobado con MinGW. Ahora me queda hacerlo con Borland.

Nuevamente darle las gracias a Diego Fazio por sus rutinas en C.

Muchas gracias !!!

Saludos,

Re: Firmar fichero con certificado

PostPosted: Sun Oct 25, 2020 8:56 am
by mgsoft
Muy interesante.

¿Funciona también para los certificados de España de la FNMT para poder firmar por ejemplo las facturas electrónicas?

Re: Firmar fichero con certificado

PostPosted: Sun Oct 25, 2020 3:09 pm
by Baxajaun
Hola Eduardo,

imagino que se podrá. Yo no lo he hecho.

Muchas gracias.

Saludos,

Re: Firmar fichero con certificado

PostPosted: Wed Feb 03, 2021 4:45 pm
by oliveiros junior
¡Hola, buenas tardes!

¿Sabe si es posible definir la ubicación de firma de documentos con este cambio con los cambios anteriores?

Pregunte además si sería posible liberar el lib hbssl que ya ha compilado?

Muchas gracias por la atención.

Oliveiros Junior

Re: Firmar fichero con certificado

PostPosted: Wed Feb 03, 2021 8:12 pm
by Baxajaun
Hola Oliveros Junior !!!

Yo he creado la lib para MinGW, no tengo ningún problema en pasarte la lib hbssl.

Saludos,

Re: Firmar fichero con certificado

PostPosted: Wed Feb 03, 2021 10:48 pm
by oliveiros junior
Hola Baxajaun,

lo siento, no había prestado atención a ese detalle. En realidad necesito compilar en FWH.

De todos modos, muchas gracias por su ayuda.

Att.,

Oliveiros Junior

Re: Firmar fichero con certificado

PostPosted: Thu Feb 04, 2021 8:10 am
by Baxajaun
Buenos días !!!
Oliveiros Junior, qué compilador de C usas ? Harbour o xHarbour ?

Muchas gracias.

Saludos,

Re: Firmar fichero con certificado

PostPosted: Thu Feb 04, 2021 10:41 am
by mgsoft
Hola,

¿Se podrían incluir estas funciones en FWH por favor?

Gracias

Re: Firmar fichero con certificado

PostPosted: Thu Feb 04, 2021 10:46 am
by Antonio Linares
Eduardo,

Si incluyésemos esas funciones en FWH se tendrían siempre que enlazar las librerías de criptografia lo cual implica tener que instalarlas, etc
y no todo el mundo las necesita

Re: Firmar fichero con certificado

PostPosted: Thu Feb 04, 2021 11:14 am
by mgsoft
Entendido.
¿Y en una librería complementaria?

Re: Firmar fichero con certificado

PostPosted: Thu Feb 04, 2021 5:30 pm
by oliveiros junior
Hola Baxajaun,

Harbour con bcc730.

Gracias.

Oliveiros Junior

Re: Firmar fichero con certificado

PostPosted: Thu Feb 04, 2021 7:16 pm
by Baxajaun
Eduardo,

has tratado de crear la lib hbssl con las rutinas en C de Diego Fazio ?

Muchas gracias.

Saludos,

Re: Firmar fichero con certificado

PostPosted: Fri Feb 05, 2021 8:44 am
by Baxajaun
Hola Oliveiros Junior !

Has tratado de crear la lib hbssl con las rutinas de Diego Fazio ? Si me das una dirección de correo, trato de crear la lib para Borland y te la envío.

Muchas gracias.

Saludos,

Re: Firmar fichero con certificado

PostPosted: Fri Feb 05, 2021 3:34 pm
by oliveiros junior
¡Hola buenos dias!

Mi correo electrónico es oliveiros.jr@uol.com.br

muchas gracias.

Oliveiros Junior

Re: Firmar fichero con certificado

PostPosted: Sat Feb 06, 2021 12:24 pm
by csincuir
Hola Baxajaun,
Podrías enviarme la librería para Borland también por favor, gracias:
sincuir@yahoo.com

Saludos

Carlos