Forum > Spanish
Ejemplo, Ayuda con Impresora Fiscal AFIP
ocloma:
Hola, cual es tu duda? yo implemente la facturacion electronica en freepascal hace varios años para la empresa donde trabajo.
Es sobre la generacion del WSAA? En caso que esta sea tu duda , la clave es escribir en formato S/MIME el mensaje que ya fue firmado con PKCS7_sign(), con la funcion SMIME_write_PKCS7(), pero esta funcion no esta disponible en la libreria openssl de lazarus, tenes que enlazarla por tu cuenta.
daragor:
Hola ocloma! buenísimo.. yo en mi caso, como dije en el primer post, me gustaria recibir un ejemplo, un codigo, una pequeña app que gestione una impresora fiscal a modo de ejemplo base para poder implementarlo en algunos sistemas lazarus..
lainz:
Algo que noté en este hilo es que se confunde lo que es una impresora fiscal con el webservice de afip, son dos cosas distintas.
Para una impresora fiscal, necesitas implementar segun el manual de la impresora fiscal.
Para el webservice de afip, como comentaron mas arriba.
ocloma:
Asi es , entendi que aqui estamos hablando particularmente del servicios de factura electronica de AFIP. Impresora fiscal es otro tema.
Hay dos servicios por separado, uno es el WSAA, que es el mas complejo y otro es el webservice en si mismo WSFE. El WSFE es el mas sencillo , ya que se puede importar el wsdl para generar las clases desde el paquete 'Web Service Tools' que se instala desde el administrador de paquetes online de Lazarus como mencionaron anteriormente. Para el WSAA, en mi caso lo tuve que implementar directamente utilizando las librerias de XML de Freepascal y OpenSSL, pero tambien se puede firmar el paquete desde las herramientas de linea de comandos que vienen con openssl.
ocloma:
Unidad para enlazar las funciones necesarias para OpenSSL (son las funciones que no se encuentran todavia enlazadas en la libreria openssl de freepascal 3.2.2):
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit UtilOpenSSL; {$MODE DELPHI}{$H+}{$Packrecords C} interface uses Classes, SysUtils; const // PADDING constants RSA_PKCS1_PADDING = 1; RSA_SSLV23_PADDING = 2; RSA_NO_PADDING = 3; RSA_PKCS1_OAEP_PADDING = 4; // ASN1 type constants NID_undef = 0; NID_rsaEncryption = 6; NID_pkcs7_signed = 22; NID_pkcs7_signedAndEnveloped = 24; NID_basic_constraints = 87; NID_subject_alt_name = 85; V_ASN1_INTEGER = $02; V_ASN1_ENUMERATED = 10; V_ASN1_NEG_INTEGER = $102; V_ASN1_UTCTIME = 23; V_ASN1_GENERALIZEDTIME = 24; V_ASN1_CONTEXT_SPECIFIC = $80; B_ASN1_NUMERICSTRING = $0001; B_ASN1_PRINTABLESTRING = $0002; B_ASN1_T61STRING = $0004; B_ASN1_TELETEXSTRING = $0008; B_ASN1_VIDEOTEXSTRING = $0008; B_ASN1_IA5STRING = $0010; B_ASN1_GRAPHICSTRING = $0020; B_ASN1_ISO64STRING = $0040; B_ASN1_VISIBLESTRING = $0040; B_ASN1_GENERALSTRING = $0080; B_ASN1_UNIVERSALSTRING = $0100; B_ASN1_OCTET_STRING = $0200; B_ASN1_BIT_STRING = $0400; B_ASN1_BMPSTRING = $0800; B_ASN1_UNKNOWN = $1000; B_ASN1_UTF8STRING = $2000; MBSTRING_FLAG = $1000; MBSTRING_ASC = MBSTRING_FLAG or 1; MBSTRING_BMP = MBSTRING_FLAG or 2; MBSTRING_UNIV = MBSTRING_FLAG or 3; MBSTRING_UTF8 = MBSTRING_FLAG or 4; // These are the 'types' of BIOs BIO_TYPE_NONE = $0000; BIO_TYPE_MEM = $0001 or $0400; BIO_TYPE_FILE = $0002 or $0400; BIO_TYPE_FD = $0004 or $0400 or $0100; BIO_TYPE_SOCKET = $0005 or $0400 or $0100; BIO_TYPE_NULL = $0006 or $0400; BIO_TYPE_SSL = $0007 or $0200; BIO_TYPE_MD = $0008 or $0200; // passive filter BIO_TYPE_BUFFER = $0009 or $0200; // filter BIO_TYPE_CIPHER = $00010 or $0200; // filter BIO_TYPE_BASE64 = $00011 or $0200; // filter BIO_TYPE_CONNECT = $00012 or $0400 or $0100; // socket - connect BIO_TYPE_ACCEPT = $00013 or $0400 or $0100; // socket for accept BIO_TYPE_PROXY_CLIENT = $00014 or $0200; // client proxy BIO BIO_TYPE_PROXY_SERVER = $00015 or $0200; // server proxy BIO BIO_TYPE_NBIO_TEST = $00016 or $0200; // server proxy BIO BIO_TYPE_NULL_FILTER = $00017 or $0200; BIO_TYPE_BER = $00018 or $0200; // BER -> bin filter BIO_TYPE_BIO = $00019 or $0400; // (half a; BIO pair BIO_TYPE_LINEBUFFER = $00020 or $0200; // filter BIO_TYPE_DESCRIPTOR = $0100; // socket, fd, connect or accept BIO_TYPE_FILTER = $0200; BIO_TYPE_SOURCE_SINK = $0400; // BIO ops constants // BIO_FILENAME_READ|BIO_CLOSE to open or close on free. // BIO_set_fp(in,stdin,BIO_NOCLOSE); BIO_NOCLOSE = $00; BIO_CLOSE = $01; BIO_FP_READ = $02; BIO_FP_WRITE = $04; BIO_FP_APPEND = $08; BIO_FP_TEXT = $10; BIO_C_SET_FILENAME = 108; BIO_CTRL_RESET = 1; // opt - rewind/zero etc BIO_CTRL_EOF = 2; // opt - are we at the eof BIO_CTRL_INFO = 3; // opt - extra tit-bits BIO_CTRL_SET = 4; // man - set the 'IO' type BIO_CTRL_GET = 5; // man - get the 'IO' type BIO_CTRL_PUSH = 6; // opt - internal, used to signify change BIO_CTRL_POP = 7; // opt - internal, used to signify change BIO_CTRL_GET_CLOSE = 8; // man - set the 'close' on free BIO_CTRL_SET_CLOSE = 9; // man - set the 'close' on free BIO_CTRL_PENDING = 10; // opt - is their more data buffered BIO_CTRL_FLUSH = 11; // opt - 'flush' buffered output BIO_CTRL_DUP = 12; // man - extra stuff for 'duped' BIO BIO_CTRL_WPENDING = 13; // opt - number of bytes still to write BIO_C_GET_MD_CTX = 120; BN_CTX_NUM = 16; BN_CTX_NUM_POS = 12; // RSA key exponent RSA_3: longint = $3; RSA_F4: longint = $10001; FORMAT_UNDEF = 0; FORMAT_ASN1 = 1; FORMAT_TEXT = 2; FORMAT_PEM = 3; FORMAT_NETSCAPE = 4; FORMAT_PKCS12 = 5; FORMAT_SMIME = 6; FORMAT_X509 = 509; PKCS7_TEXT = $001; PKCS7_NOCERTS = $002; PKCS7_NOSIGS = $004; PKCS7_NOCHAIN = $008; PKCS7_NOINTERN = $010; PKCS7_NOVERIFY = $020; PKCS7_DETACHED = $040; PKCS7_BINARY = $080; PKCS7_NOATTR = $100; PKCS7_NOSMIMECAP = $200; PKCS7_NOOLDMIMETYPE = $400; PKCS7_CRLFEOL = $800; PKCS7_STREAM = $1000; PKCS7_NOCRL = $2000; PKCS7_PARTIAL = $4000; PKCS7_REUSE_DIGEST = $8000; X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 18; SHA_DIGEST_LENGTH = 20; EVP_MAX_MD_SIZE = 16 + 20; // SSLv3 md5+sha1 EVP_PKEY_RSA = NID_rsaEncryption; EXFLAG_KUSAGE = $02; EXFLAG_BCONS = $1; EXFLAG_CA = $10; EXFLAG_SS = $20; EXFLAG_V1 = $40; KU_KEY_CERT_SIGN = $0004; V1_ROOT = EXFLAG_V1 or EXFLAG_SS; GEN_OTHERNAME = 0 or V_ASN1_CONTEXT_SPECIFIC; GEN_EMAIL = 1 or V_ASN1_CONTEXT_SPECIFIC; GEN_DNS = 2 or V_ASN1_CONTEXT_SPECIFIC; GEN_X400 = 3 or V_ASN1_CONTEXT_SPECIFIC; GEN_DIRNAME = 4 or V_ASN1_CONTEXT_SPECIFIC; GEN_EDIPARTY = 5 or V_ASN1_CONTEXT_SPECIFIC; GEN_URI = 6 or V_ASN1_CONTEXT_SPECIFIC; GEN_IPADD = 7 or V_ASN1_CONTEXT_SPECIFIC; GEN_RID = 8 or V_ASN1_CONTEXT_SPECIFIC; type PCharacter = PChar; pSTACK = pointer; // ASN1 types pASN1_OBJECT = pointer; pASN1_STRING = ^ASN1_STRING; ASN1_STRING = record length: integer; asn1_type: integer; Data: pointer; flags: longint; end; pASN1_IA5STRING = pASN1_STRING; pASN1_INTEGER = pASN1_STRING; pASN1_ENUMERATED = pASN1_STRING; pASN1_TIME = pASN1_STRING; pASN1_OCTET_STRING = pASN1_STRING; pBN_ULONG = ^BN_ULONG; BN_ULONG = array of byte; pBIGNUM = ^BIGNUM; BIGNUM = record d: pBN_ULONG; top: integer; dmax: integer; neg: integer; flags: integer; end; pBN_CTX = ^BN_CTX; BN_CTX = record tos: integer; bn: array [0..BN_CTX_NUM - 1] of BIGNUM; flags: integer; depth: integer; pos: array [0..BN_CTX_NUM_POS - 1] of integer; too_many: integer; end; pBN_BLINDING = ^BN_BLINDING; BN_BLINDING = record init: integer; A: pBIGNUM; Ai: pBIGNUM; _mod: pBIGNUM; end; pBN_MONT_CTX = ^BN_MONT_CTX; BN_MONT_CTX = record ri: integer; RR: BIGNUM; N: BIGNUM; Ni: BIGNUM; n0: BN_ULONG; flags: integer; end; pBN_RECP_CTX = ^BN_RECP_CTX; BN_RECP_CTX = record N: BIGNUM; Nr: BIGNUM; num_bits: integer; shift: integer; flags: integer; end; pX509_STORE_CTX = pointer; TPWCallbackFunction = function(buffer: PCharacter; length: integer; verify: integer; Data: pointer): integer; cdecl; TCertificateVerifyFunction = function(ok: integer; ctx: pX509_STORE_CTX): integer; cdecl; pBIO = pointer; pBIO_METHOD = pointer; pBUF_MEM = pointer; des_cblock = array [0..7] of byte; MD2_CTX = record num: integer; Data: array [0..15] of byte; cksm: array [0..15] of cardinal; state: array [0..15] of cardinal; end; MD4_CTX = record A, B, C, D: cardinal; Nl, Nh: cardinal; Data: array [0..15] of cardinal; num: integer; end; MD5_CTX = record A, B, C, D: cardinal; Nl, Nh: cardinal; Data: array [0..15] of cardinal; num: integer; end; RIPEMD160_CTX = record A, B, C, D, E: cardinal; Nl, Nh: cardinal; Data: array [0..15] of cardinal; num: integer; end; SHA_CTX = record h0, h1, h2, h3, h4: cardinal; Nl, Nh: cardinal; Data: array [0..16] of cardinal; num: integer; end; MDC2_CTX = record num: integer; Data: array [0..7] of byte; h, hh: des_cblock; pad_type: integer; end; CRYPTO_EX_DATA = record sk: pointer; dummy: integer; end; pAES_KEY = pointer; pRSA = pointer; pRSA_METHOD = pointer; RSA = record pad: integer; version: integer; meth: pRSA_METHOD; n: pBIGNUM; e: pBIGNUM; d: pBIGNUM; p: pBIGNUM; q: pBIGNUM; dmp1: pBIGNUM; dmq1: pBIGNUM; iqmp: pBIGNUM; ex_data: CRYPTO_EX_DATA; references: integer; flags: integer; _method_mod_n: pBN_MONT_CTX; _method_mod_p: pBN_MONT_CTX; _method_mod_q: pBN_MONT_CTX; bignum_data: ^byte; blinding: ^BN_BLINDING; end; pDSA = ^DSA; DSA = record pad: integer; version: integer; write_params: integer; p: pointer; q: pointer; g: pointer; pub_key: pointer; priv_key: pointer; kinv: pointer; r: pointer; flags: integer; method_mont_p: PCharacter; references: integer; ex_data: record sk: pointer; dummy: integer; end; meth: pointer; end; pDH = pointer; pEC_KEY = pointer; pEVP_CIPHER = pointer; pEVP_MD = ^EVP_MD; EVP_MD = record _type: integer; pkey_type: integer; md_size: integer; init: pointer; update: pointer; final: pointer; sign: pointer; verify: pointer; required_pkey_type: array [0..4] of integer; block_size: integer; ctx_size: integer; end; pEVP_MD_CTX = ^EVP_MD_CTX; EVP_MD_CTX = record digest: pEVP_MD; case integer of 0: (base: array [0..3] of byte); 1: (md2: MD2_CTX); 8: (md4: MD4_CTX); 2: (md5: MD5_CTX); 16: (ripemd160: RIPEMD160_CTX); 4: (sha: SHA_CTX); 32: (mdc2: MDC2_CTX); end; pX509_NAME_ENTRY = ^X509_NAME_ENTRY; X509_NAME_ENTRY = record obj: pASN1_OBJECT; Value: pASN1_STRING; _set: integer; size: integer; // temp variable end; pX509_NAME = ^X509_NAME; pDN = ^X509_NAME; X509_NAME = record entries: pointer; modified: integer; bytes: pointer; hash: cardinal; end; pX509_VAL = ^X509_VAL; X509_VAL = record notBefore: pASN1_TIME; notAfter: pASN1_TIME; end; pX509_CINF = ^X509_CINF; X509_CINF = record version: pointer; serialNumber: pointer; signature: pointer; issuer: pointer; validity: pX509_VAL; subject: pointer; key: pointer; issuerUID: pointer; subjectUID: pointer; extensions: pointer; end; pX509 = ^X509; X509 = record cert_info: pX509_CINF; sig_alg: pointer; // ^X509_ALGOR signature: pointer; // ^ASN1_BIT_STRING valid: integer; references: integer; Name: PCharacter; ex_data: CRYPTO_EX_DATA; ex_pathlen: integer; ex_flags: integer; ex_kusage: integer; ex_xkusage: integer; ex_nscert: integer; skid: pASN1_OCTET_STRING; akid: pointer; // ? sha1_hash: array [0..SHA_DIGEST_LENGTH - 1] of char; aux: pointer; // ^X509_CERT_AUX end; pSTACK_OFX509 = pointer; pX509_STORE = ^X509_STORE; pX509_LOOKUP = pointer; pSTACK_OF509LOOKUP = pointer; pX509_LOOKUP_METHOD = pointer; X509_STORE = record cache: integer; objs: pSTACK_OFX509; get_cert_methods: pSTACK_OF509LOOKUP; verify: pointer; // function called to verify a certificate verify_cb: TCertificateVerifyFunction; ex_data: pointer; references: integer; depth: integer; end; pX509V3_CTX = pointer; pX509_REQ = ^X509_REQ; pX509_REQ_INFO = ^X509_REQ_INFO; X509_REQ_INFO = record asn1: pointer; length: integer; version: pointer; subject: pX509_NAME; pubkey: pointer; attributes: pointer; req_kludge: integer; end; X509_REQ = record req_info: pX509_REQ_INFO; sig_alg: pointer; signature: pointer; references: integer; end; pX509_EXTENSION = ^X509_EXTENSION; X509_EXTENSION = record obj: pASN1_OBJECT; critical: smallint; netscape_hack: smallint; Value: pASN1_OCTET_STRING; method: pointer; // struct v3_ext_method *: V3 method to use ext_val: pointer; // extension value end; pSTACK_OFX509_EXTENSION = pointer; pX509_CRL = pointer; pX509_SIG = ^X509_SIG; X509_SIG = record algor: Pointer; // X509_ALGOR *algor; digest: pASN1_OCTET_STRING; end; pBASIC_CONSTRAINTS = ^BASIC_CONSTRAINTS; BASIC_CONSTRAINTS = record ca: integer; pathlen: pASN1_INTEGER; end; pOTHERNAME = ^OTHERNAME; OTHERNAME = record type_id: pASN1_OBJECT; //There is a bug in x509v3/x509v3.h ? Value: pointer; //pASN1_TYPE; end; pGENERAL_NAME = ^GENERAL_NAME; pGENERAL_NAMEDATA = record case integer of GEN_EMAIL: (ia5: pASN1_IA5STRING); // also DNS and URI GEN_IPADD: (ip: pASN1_OCTET_STRING); GEN_DIRNAME: (dirn: pX509_NAME); GEN_RID: (rid: pASN1_OBJECT); GEN_OTHERNAME: (otherName: pOTHERNAME); GEN_X400: (other: pointer); // also EDI end; GENERAL_NAME = record nametype: integer; d: pGENERAL_NAMEDATA; end; pEVP_PKEY = ^EVP_PKEY; EVP_PKEY_PKEY = record case integer of 0: (ptr: PCharacter); 1: (rsa: pRSA); // ^rsa_st 2: (dsa: pDSA); // ^dsa_st 3: (dh: pDH); // ^dh_st end; EVP_PKEY = record ktype: integer; save_type: integer; references: integer; pkey: EVP_PKEY_PKEY; save_parameters: integer; attributes: pSTACK_OFX509; end; pPKCS7_SIGNER_INFO = pointer; pSTACK_OFPKCS7_SIGNER_INFO = pointer; pPKCS7_signed = ^PKCS7_signed; PKCS7_signed = record version: pASN1_INTEGER; md_algs: pointer; // ^STACK_OF(X509_ALGOR) cert: pointer; // ^STACK_OF(X509) crl: pointer; // ^STACK_OF(X509_CRL) signer_info: pSTACK_OFPKCS7_SIGNER_INFO; contents: pointer; // ^struct pkcs7_st end; pPKCS7_signedandenveloped = ^PKCS7_signedandenveloped; PKCS7_signedandenveloped = record version: pASN1_INTEGER; md_algs: pointer; // ^STACK_OF(X509_ALGOR) cert: pointer; // ^STACK_OF(X509) crl: pointer; // ^STACK_OF(X509_CRL) signer_info: pSTACK_OFPKCS7_SIGNER_INFO; enc_data: pointer; // ^PKCS7_ENC_CONTENT recipientinfo: pointer; // ^STACK_OF(PKCS7_RECIP_INFO) end; pPKCS7 = ^PKCS7; PKCS7 = record asn1: PCharacter; length: integer; state: integer; detached: integer; asn1_type: pointer; // ^ASN1_OBJECT case integer of 0: (ptr: pASN1_OCTET_STRING); 1: (Data: pointer); // ^PKCS7_SIGNED 2: (sign: pPKCS7_signed); // ^PKCS7_SIGNED 3: (enveloped: pointer); // ^PKCS7_ENVELOPE 4: (signed_and_enveloped: pPKCS7_signedandenveloped); 5: (digest: pointer); // ^PKCS7_DIGEST 6: (encrypted: pointer); // ^PKCS7_ENCRYPT 7: (other: pointer); // ^ASN1_TYPE end; { void OpenSSL_add_all_algorithms(void); void OpenSSL_add_all_ciphers(void); void OpenSSL_add_all_digests(void); }procedure OpenSSL_add_all_algorithms; cdecl;procedure OpenSSL_add_all_ciphers; cdecl;procedure OpenSSL_add_all_digests; cdecl; procedure CRYPTO_cleanup_all_ex_data(); cdecl;procedure EVP_cleanup(); cdecl;procedure ERR_load_crypto_strings; cdecl;procedure ERR_free_strings; cdecl; // BIOfunction BIO_new(_type: pBIO_METHOD): pBIO; cdecl;function BIO_free(a: pBIO): integer; cdecl;procedure BIO_free_all(a: pBIO); cdecl;function BIO_ctrl(bp: pBIO; cmd: integer; larg: longint; parg: Pointer): longint; cdecl;function BIO_read(b: pBIO; buf: pointer; len: integer): integer; cdecl;function BIO_reset(bp: pBIO): integer;function BIO_pending(bp: pBIO): integer;function BIO_read_filename(bp: pBIO; filename: PCharacter): integer;function BIO_s_mem: pBIO_METHOD; cdecl;function BIO_new_mem_buf(buf: pointer; len: integer): pBIO; cdecl;function BIO_s_file: pBIO_METHOD; cdecl; // PEMfunction PEM_read_bio_X509(bp: pBIO; var x: pX509; cb: TPWCallbackFunction; u: pointer): pX509; cdecl;function PEM_read_bio_PrivateKey(bp: pBIO; var x: pEVP_PKEY; cb: TPWCallbackFunction; u: pointer): pEVP_PKEY; cdecl; // PKCS#7 functionsfunction PKCS7_sign(signcert: pX509; pkey: pEVP_PKEY; certs: pointer; Data: pBIO; flags: integer): pPKCS7; cdecl;procedure PKCS7_free(p7: pPKCS7); cdecl; // SMIMEfunction SMIME_write_PKCS7(bp: pBIO; p7: pPKCS7; Data: pBIO; flags: integer): integer; cdecl;function SMIME_read_PKCS7(bp: pBIO; var bcont: pBIO): pPKCS7; cdecl; implementation const Crypto_DLL_Names = 'libeay32.dll'; //libcrypto-1_1 o libcrypto-3 procedure OpenSSL_add_all_algorithms; external Crypto_DLL_Names;procedure OpenSSL_add_all_ciphers; external Crypto_DLL_Names;procedure OpenSSL_add_all_digests; external Crypto_DLL_Names;procedure EVP_cleanup; external Crypto_DLL_Names; procedure CRYPTO_cleanup_all_ex_data; external Crypto_DLL_Names;procedure ERR_load_crypto_strings; external Crypto_DLL_Names;procedure ERR_free_strings; external Crypto_DLL_Names;//BIOfunction BIO_new; external Crypto_DLL_Names;function BIO_free; external Crypto_DLL_Names;procedure BIO_vfree; external Crypto_DLL_Names;procedure BIO_free_all; external Crypto_DLL_Names;function BIO_ctrl; external Crypto_DLL_Names;function BIO_read; external Crypto_DLL_Names;function BIO_s_mem; external Crypto_DLL_Names;procedure BIO_set_mem_buf; external Crypto_DLL_Names;procedure BIO_get_mem_ptr; external Crypto_DLL_Names;function BIO_new_mem_buf; external Crypto_DLL_Names;function BIO_s_file; external Crypto_DLL_Names; function BIO_reset(bp: pBIO): integer;begin Result := BIO_ctrl(bp, BIO_CTRL_RESET, 0, nil);end; function BIO_pending(bp: pBIO): integer;begin Result := BIO_ctrl(bp, BIO_CTRL_PENDING, 0, nil);end; function BIO_read_filename(bp: pBIO; filename: PCharacter): integer;begin Result := BIO_ctrl(bp, BIO_C_SET_FILENAME, BIO_CLOSE or BIO_FP_READ, filename);end; // PEMfunction PEM_read_bio_X509; external Crypto_DLL_Names;function PEM_read_bio_PrivateKey; external Crypto_DLL_Names; // PKCS#7function PKCS7_sign; external Crypto_DLL_Names;procedure PKCS7_free; external Crypto_DLL_Names; // SMIMEfunction SMIME_write_PKCS7; external Crypto_DLL_Names;function SMIME_read_PKCS7; external Crypto_DLL_Names; end.
Navigation
[0] Message Index
[#] Next page
[*] Previous page