Firmar fichero con certificado

User avatar
Baxajaun
Posts: 969
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Firmar fichero con certificado

Post by Baxajaun »

Buenas tardes !!!

Las gracias y el reconocimiento a Diego Fazio.

cms.c

Code: Select all | Expand

#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

#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

-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

#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

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

Code: Select all | Expand

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

Code: Select all | Expand

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,
User avatar
mgsoft
Posts: 422
Joined: Mon Aug 17, 2009 12:18 pm
Location: España

Re: Firmar fichero con certificado

Post 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?
Saludos,

Eduardo
User avatar
Baxajaun
Posts: 969
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Re: Firmar fichero con certificado

Post by Baxajaun »

Hola Eduardo,

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

Muchas gracias.

Saludos,
oliveiros junior
Posts: 128
Joined: Tue Mar 20, 2007 3:13 pm
Has thanked: 1 time

Re: Firmar fichero con certificado

Post 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
User avatar
Baxajaun
Posts: 969
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Re: Firmar fichero con certificado

Post by Baxajaun »

Hola Oliveros Junior !!!

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

Saludos,
oliveiros junior
Posts: 128
Joined: Tue Mar 20, 2007 3:13 pm
Has thanked: 1 time

Re: Firmar fichero con certificado

Post 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
User avatar
Baxajaun
Posts: 969
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Re: Firmar fichero con certificado

Post by Baxajaun »

Buenos días !!!
Oliveiros Junior, qué compilador de C usas ? Harbour o xHarbour ?

Muchas gracias.

Saludos,
User avatar
mgsoft
Posts: 422
Joined: Mon Aug 17, 2009 12:18 pm
Location: España

Re: Firmar fichero con certificado

Post by mgsoft »

Hola,

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

Gracias
Saludos,

Eduardo
User avatar
Antonio Linares
Site Admin
Posts: 42548
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 78 times
Contact:

Re: Firmar fichero con certificado

Post 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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
mgsoft
Posts: 422
Joined: Mon Aug 17, 2009 12:18 pm
Location: España

Re: Firmar fichero con certificado

Post by mgsoft »

Entendido.
¿Y en una librería complementaria?
Saludos,

Eduardo
oliveiros junior
Posts: 128
Joined: Tue Mar 20, 2007 3:13 pm
Has thanked: 1 time

Re: Firmar fichero con certificado

Post by oliveiros junior »

Hola Baxajaun,

Harbour con bcc730.

Gracias.

Oliveiros Junior
User avatar
Baxajaun
Posts: 969
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Re: Firmar fichero con certificado

Post by Baxajaun »

Eduardo,

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

Muchas gracias.

Saludos,
User avatar
Baxajaun
Posts: 969
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Re: Firmar fichero con certificado

Post 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,
oliveiros junior
Posts: 128
Joined: Tue Mar 20, 2007 3:13 pm
Has thanked: 1 time

Re: Firmar fichero con certificado

Post by oliveiros junior »

¡Hola buenos dias!

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

muchas gracias.

Oliveiros Junior
csincuir
Posts: 415
Joined: Sat Feb 03, 2007 6:36 am
Location: Guatemala
Has thanked: 3 times
Been thanked: 2 times
Contact:

Re: Firmar fichero con certificado

Post by csincuir »

Hola Baxajaun,
Podrías enviarme la librería para Borland también por favor, gracias:
sincuir@yahoo.com

Saludos

Carlos
Post Reply