Page 1 of 1

Firmar fichero con certificado

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

Las gracias y el reconocimiento a Diego Fazio.

cms.c

Code: Select all

#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

#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

-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

#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

libcrypto-1_1.dll
libssl-1_1.dll
 
y he añadido las siguientes libs de Harbour:

Code: Select all

libcrypto-1_1.a 
libssl-1_1.a
 
Y también he añadido las siguientes libs de MinGW:

Code: Select all

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

Posted: 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

Posted: 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

Posted: 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 _ 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

Posted: 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

Posted: 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

Posted: 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

Posted: 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

Posted: 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

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

Re: Firmar fichero con certificado

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

Harbour con bcc730.

Gracias.

Oliveiros Junior

Re: Firmar fichero con certificado

Posted: 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

Posted: 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

Posted: 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

Posted: 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