Compare commits
	
		
			145 Commits
		
	
	
		
			v0.2.1
			...
			Habilitaci
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f97b3d8317 | |||
| e539f1e0a7 | |||
| 7972a3f59c | |||
| 20d8f4284f | |||
| c49e67b8a6 | |||
| 7672ae4b7f | |||
| 25c5fda3f0 | |||
| a758b8678b | |||
| 3a385c63e3 | |||
| 9b33b4486c | |||
| 612aae1f86 | |||
| 4fe82daac6 | |||
| e237d1b45f | |||
| 8cc6146be2 | |||
| f98ab98c9c | |||
| d04596ed3a | |||
| 9297be22e0 | |||
|  | 30773e042b | ||
|  | c919d8e36c | ||
| fb44498e53 | |||
| 9f7349ccee | |||
| 9cc41e1c5d | |||
| fc75126ca0 | |||
| d061077b30 | |||
| a3d2176068 | |||
| 98677bc162 | |||
| 398d27d049 | |||
| 8765a3d2c8 | |||
| 1935ed3048 | |||
| 097cf97fc3 | |||
| de99633211 | |||
|  | 028cf8b687 | ||
| e7a3976b14 | |||
| f08954ee43 | |||
| a0321020c7 | |||
| dde24b9739 | |||
| 6e5d358c73 | |||
| c12d985f76 | |||
| 9c126d961b | |||
| 95f16b2842 | |||
| 8f327f7abc | |||
|  | b7c9f2b201 | ||
| 7f974b7077 | |||
| 78477de2c2 | |||
|   | 75b41379c4 | ||
|   | d26cc2bef7 | ||
|   | 1abf34d4f0 | ||
|  | 3862b3e934 | ||
|   | 5cf929cca9 | ||
|   | 7e51726a0d | ||
|  | f05eb61d6e | ||
|  | 5a045ccdef | ||
|   | bd0fe70f33 | ||
|   | 7c4c9648fe | ||
|  | 5eecae0740 | ||
|  | a59df60fc2 | ||
|  | 19c5a5bca6 | ||
|  | c50f1df1e7 | ||
|  | 2a1f3b6b43 | ||
|  | a208d924dd | ||
|  | c3b0f7cfe8 | ||
|  | 005f90166e | ||
|  | 73bb90b74b | ||
|  | 6bed600dd4 | ||
|  | aa3c83933d | ||
|  | ac1678b1cc | ||
|  | 29db6b0342 | ||
|  | 417de535f3 | ||
|  | a9564f9a70 | ||
|  | 48c56631ec | ||
|  | d5f484ac30 | ||
|  | fc904f8f92 | ||
|  | 6e2f450ee9 | ||
|  | 099b23df74 | ||
|  | 82e043e01d | ||
|  | 7054e2da22 | ||
|  | dc9e0d9ad7 | ||
|  | c08629337c | ||
|  | 95bc4e73f5 | ||
|  | a411562af1 | ||
|  | 27ebbecc01 | ||
|  | 7181c004cb | ||
|  | 012615f984 | ||
|  | a320b5a7b0 | ||
|  | ebc67d1327 | ||
|  | 9c2c3d9ce3 | ||
|  | d36259d121 | ||
|  | 23d6f668bf | ||
|  | dd445b59f0 | ||
|  | 1a302f605f | ||
|  | cbe0c512eb | ||
|  | 1e03d4f289 | ||
|  | ec391f93f6 | ||
|  | 27208c46ec | ||
|  | c861cf5a79 | ||
|  | e88c2dd83b | ||
|  | 67f29fcca6 | ||
|  | ee3910136d | ||
|  | ab1646f156 | ||
|  | e13896db28 | ||
|  | 44f551ff77 | ||
|  | c1cdd4815c | ||
|  | b52a90dd76 | ||
|  | a4d0d214dc | ||
|  | 248ec4304d | ||
|  | 4ceec2ca53 | ||
|  | 49a6cb75ff | ||
|  | 6d02ad0bf5 | ||
|  | 0c28eea6e2 | ||
|  | 56c7e2c453 | ||
|  | cd1b14ff1d | ||
|  | 903b1bad64 | ||
|  | aa3e14de95 | ||
|  | fb88d56652 | ||
|  | a34963ca49 | ||
|  | 8deebbdfa4 | ||
|  | b23be4b42f | ||
|  | f7a29b6daa | ||
|  | 080014cbb6 | ||
|  | d152da31ed | ||
|  | 311bfef3e3 | ||
|  | bb16b5e968 | ||
|  | b60fe675c1 | ||
|  | 0e5235b095 | ||
|  | d5fd7db23c | ||
|  | 3ec31c36b4 | ||
|  | 8d17c282e3 | ||
|  | 35e1c5b609 | ||
|  | 3b2e3ff8a0 | ||
|  | 4b11f6b06d | ||
|  | 791d534653 | ||
|  | 74d98e249d | ||
|  | 3ef002e137 | ||
|  | c758912cf2 | ||
|  | 18342b7e23 | ||
|  | 1602dd35e3 | ||
|  | 7f72bab06a | ||
|  | adbd6d0d0e | ||
|  | 2b76cf6a10 | ||
|  | f975e666ee | ||
|  | fcd5060485 | ||
|  | f627e3e22a | ||
|  | 58307bf9cf | ||
|  | 9199af9b68 | ||
|  | 4c871afb73 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -215,3 +215,4 @@ tags | |||||||
| pyvenv.cfg | pyvenv.cfg | ||||||
| .venv | .venv | ||||||
| pip-selfcheck.json | pip-selfcheck.json | ||||||
|  | invoice.xml | ||||||
							
								
								
									
										31
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | # DERIVADO DE https://alextereshenkov.github.io/run-python-tests-with-tox-in-docker.html | ||||||
|  | FROM ubuntu:18.04 | ||||||
|  |  | ||||||
|  | RUN apt-get -qq update | ||||||
|  | RUN apt-get install -y --no-install-recommends \ | ||||||
|  |   python3.7 python3.7-distutils python3.7-dev \ | ||||||
|  |   python3.8 python3.8-distutils python3.8-dev \ | ||||||
|  |   wget \ | ||||||
|  |   ca-certificates | ||||||
|  |  | ||||||
|  | RUN wget https://bootstrap.pypa.io/get-pip.py \ | ||||||
|  |   && python3 get-pip.py pip==21.3 \ | ||||||
|  |   && python3.7 get-pip.py pip==21.3 \ | ||||||
|  |   && python3.8 get-pip.py pip==21.3 \ | ||||||
|  |   && rm get-pip.py | ||||||
|  |  | ||||||
|  | RUN apt-get install -y --no-install-recommends \ | ||||||
|  |         libxml2-dev \ | ||||||
|  |         libxmlsec1-dev \ | ||||||
|  |         build-essential \ | ||||||
|  |         zip | ||||||
|  |  | ||||||
|  | RUN python3.6 --version | ||||||
|  | RUN python3.7 --version | ||||||
|  | RUN python3.8 --version | ||||||
|  |  | ||||||
|  | RUN pip3.6 install setuptools setuptools-rust | ||||||
|  | RUN pip3.7 install setuptools setuptools-rust | ||||||
|  | RUN pip3.8 install setuptools setuptools-rust | ||||||
|  |  | ||||||
|  | RUN pip3 install tox pytest | ||||||
							
								
								
									
										24
									
								
								Makefile.dev
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Makefile.dev
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | # Entorno de desarrollo | ||||||
|  | # | ||||||
|  | # solo es necesario una vez: | ||||||
|  | #  * make -f Makefile.dev dev-setup | ||||||
|  | # | ||||||
|  | # luego se pueden ejecutar las pruebas: | ||||||
|  | #  * make -f Makefile.dev test | ||||||
|  |  | ||||||
|  | .PHONY: dev-setup dev-shell py-develop test tox | ||||||
|  |  | ||||||
|  | dev-setup: | ||||||
|  | 	docker build -t facho . | ||||||
|  |  | ||||||
|  | py-develop: | ||||||
|  | 	docker run -t -v $(PWD):/app -w /app facho sh -c 'python3.7 setup.py develop --user' | ||||||
|  |  | ||||||
|  | dev-shell: | ||||||
|  | 	docker run --rm -ti -v "$(PWD):/app" -w /app --name facho-cli facho bash | ||||||
|  |  | ||||||
|  | test: | ||||||
|  | 	docker run -t -v $(PWD):/app -w /app facho sh -c 'cd /app; python3.7 setup.py test' | ||||||
|  |  | ||||||
|  | tox: | ||||||
|  | 	docker run -it -v $(PWD)/:/app -w /app facho tox | ||||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										14706
									
								
								docs/DIAN/nomina/Anexo Tecnico 11-02-2021.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14706
									
								
								docs/DIAN/nomina/Anexo Tecnico 11-02-2021.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										13
									
								
								docs/DIAN/nomina/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								docs/DIAN/nomina/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | # notas | ||||||
|  |  | ||||||
|  | * se extrae documento tecnico de resolucion usando **pdfarranger** | ||||||
|  |  | ||||||
|  | ## CUNE | ||||||
|  |  | ||||||
|  |  ver 8.1.1.1 del archivo **Resolucion 000013 de 11-02-2021.pdf** | ||||||
|  |  | ||||||
|  | # enlaces | ||||||
|  |  | ||||||
|  | * https://www.dian.gov.co/impuestos/Paginas/Sistema-de-Factura-Electronica/documento-soporte-de-pago-de-nomina-electronica.aspx | ||||||
|  | * https://bitbucket.org/presik/electronic_payroll.git | ||||||
|  | * https://bitbucket.org/presik/trytonpsk-staff_payroll_co.git | ||||||
							
								
								
									
										
											BIN
										
									
								
								docs/DIAN/nomina/Resolución 000013 de 11-02-2021.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/DIAN/nomina/Resolución 000013 de 11-02-2021.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										93
									
								
								examples/generate-nomina-from-cli.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								examples/generate-nomina-from-cli.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  |  | ||||||
|  | from facho import fe | ||||||
|  |  | ||||||
|  | def extensions(nomina): | ||||||
|  |     return [] | ||||||
|  |  | ||||||
|  | def nomina(): | ||||||
|  |     nomina = fe.nomina.DIANNominaIndividual() | ||||||
|  |  | ||||||
|  |     nomina.asignar_metadata(fe.nomina.Metadata( | ||||||
|  |         secuencia=fe.nomina.NumeroSecuencia( | ||||||
|  |             numero = 'N00001', | ||||||
|  |             consecutivo=232 | ||||||
|  |         ), | ||||||
|  |         lugar_generacion=fe.nomina.Lugar( | ||||||
|  |             pais = fe.nomina.Pais( | ||||||
|  |                 code = 'CO' | ||||||
|  |             ), | ||||||
|  |             departamento = fe.nomina.Departamento( | ||||||
|  |                 code = '05' | ||||||
|  |             ), | ||||||
|  |             municipio = fe.nomina.Municipio( | ||||||
|  |                 code = '05001' | ||||||
|  |             ), | ||||||
|  |         ), | ||||||
|  |         proveedor=fe.nomina.Proveedor( | ||||||
|  |             nit='999999', | ||||||
|  |             dv=2, | ||||||
|  |             software_id='xx', | ||||||
|  |             software_sc='yy' | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_informacion_general(fe.nomina.InformacionGeneral( | ||||||
|  |         fecha_generacion = '2020-01-16', | ||||||
|  |         hora_generacion = '1053:10-05:00', | ||||||
|  |         tipo_ambiente = fe.nomina.InformacionGeneral.AMBIENTE_PRODUCCION, | ||||||
|  |         software_pin = '693', | ||||||
|  |         periodo_nomina = fe.nomina.PeriodoNomina(code='1'), | ||||||
|  |         tipo_moneda = fe.nomina.TipoMoneda(code='COP') | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_empleador(fe.nomina.Empleador( | ||||||
|  |         nit = '700085371', | ||||||
|  |         dv = '1', | ||||||
|  |         pais = fe.nomina.Pais( | ||||||
|  |             code = 'CO' | ||||||
|  |         ), | ||||||
|  |         departamento = fe.nomina.Departamento( | ||||||
|  |             code = '05' | ||||||
|  |         ), | ||||||
|  |         municipio = fe.nomina.Municipio( | ||||||
|  |             code = '05001' | ||||||
|  |         ), | ||||||
|  |         direccion = 'calle etrivial' | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_trabajador(fe.nomina.Trabajador( | ||||||
|  |         tipo_contrato = fe.nomina.TipoContrato( | ||||||
|  |             code = '1' | ||||||
|  |         ), | ||||||
|  |         alto_riesgo = False, | ||||||
|  |         tipo_documento = fe.nomina.TipoDocumento( | ||||||
|  |             code = '11' | ||||||
|  |         ), | ||||||
|  |         primer_apellido = 'gnu', | ||||||
|  |         segundo_apellido = 'emacs', | ||||||
|  |         primer_nombre = 'facho', | ||||||
|  |         lugar_trabajo = fe.nomina.LugarTrabajo( | ||||||
|  |             pais = fe.nomina.Pais(code='CO'), | ||||||
|  |             departamento = fe.nomina.Departamento(code='05'), | ||||||
|  |             municipio = fe.nomina.Municipio(code='05001'), | ||||||
|  |             direccion = 'calle facho' | ||||||
|  |         ), | ||||||
|  |         numero_documento = '800199436', | ||||||
|  |         tipo = fe.nomina.TipoTrabajador( | ||||||
|  |             code = '01' | ||||||
|  |         ), | ||||||
|  |         salario_integral = True, | ||||||
|  |         sueldo = fe.nomina.Amount(1_500_000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_devengado(fe.nomina.DevengadoBasico( | ||||||
|  |         dias_trabajados = 60, | ||||||
|  |         sueldo_trabajado = fe.nomina.Amount(3_500_000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_deduccion(fe.nomina.DeduccionSalud( | ||||||
|  |         porcentaje = fe.nomina.Amount(19), | ||||||
|  |         deduccion = fe.nomina.Amount(1_000_000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     return nomina | ||||||
							
								
								
									
										123
									
								
								examples/habilitacion/N000001.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								examples/habilitacion/N000001.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  |  | ||||||
|  | from facho import fe | ||||||
|  |  | ||||||
|  | SOFTWARE_PIN='20234' | ||||||
|  | SOFTWARE_ID='100b0d10-0ca0-4ad4-a894-b704a568cbf3' | ||||||
|  | NIT='901575528' | ||||||
|  | DV='2' | ||||||
|  |  | ||||||
|  | def extensions(nomina): | ||||||
|  |     return [] | ||||||
|  |  | ||||||
|  | def nomina(): | ||||||
|  |     nomina = fe.nomina.DIANNominaIndividual() | ||||||
|  |  | ||||||
|  |     nomina.asignar_fecha_pago('2024-04-30') | ||||||
|  |  | ||||||
|  |     nomina.asignar_metadata(fe.nomina.Metadata( | ||||||
|  |     novedad=fe.nomina.Novedad(value='false'), | ||||||
|  |         secuencia=fe.nomina.NumeroSecuencia( | ||||||
|  |             prefijo='N', | ||||||
|  |             consecutivo='000001' | ||||||
|  |         ), | ||||||
|  |         lugar_generacion=fe.nomina.Lugar( | ||||||
|  |             pais = fe.nomina.Pais( | ||||||
|  |                 code = 'CO' | ||||||
|  |             ), | ||||||
|  |             departamento = fe.nomina.Departamento( | ||||||
|  |                 code = '05' | ||||||
|  |             ), | ||||||
|  |             municipio = fe.nomina.Municipio( | ||||||
|  |                 code = '05001' | ||||||
|  |             ), | ||||||
|  |         ), | ||||||
|  |         proveedor=fe.nomina.Proveedor( | ||||||
|  | 	    razon_social='BICI PIZZA S.A.S', | ||||||
|  |             nit=NIT, | ||||||
|  |             dv=DV, | ||||||
|  |             software_id=SOFTWARE_ID, | ||||||
|  |             software_pin=SOFTWARE_PIN | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_periodo(fe.nomina.Periodo( | ||||||
|  |         fecha_ingreso= '2022-01-05', | ||||||
|  |         fecha_liquidacion_inicio='2024-04-01', | ||||||
|  |         fecha_liquidacion_fin='2024-04-30', | ||||||
|  |         fecha_generacion='2024-04-30' | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_informacion_general(fe.nomina.InformacionGeneral( | ||||||
|  |         fecha_generacion = '2024-04-30', | ||||||
|  |         hora_generacion = '08:01:00-05:00', | ||||||
|  |         tipo_ambiente = fe.nomina.InformacionGeneral.AMBIENTE_PRUEBAS, | ||||||
|  |         software_pin = SOFTWARE_PIN, | ||||||
|  |         periodo_nomina = fe.nomina.PeriodoNomina(code='1'), | ||||||
|  |         tipo_moneda = fe.nomina.TipoMoneda(code='COP') | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_pago(fe.nomina.Pago( | ||||||
|  |         forma=fe.nomina.FormaPago( | ||||||
|  |             code='1', | ||||||
|  |         ), | ||||||
|  |         metodo=fe.nomina.MetodoPago( | ||||||
|  |             code='10' | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |     nomina.asignar_empleador(fe.nomina.Empleador( | ||||||
|  | 	razon_social='BICI PIZZA S.A.S', | ||||||
|  |         nit = NIT, | ||||||
|  |         dv = DV, | ||||||
|  |         pais = fe.nomina.Pais( | ||||||
|  |             code = 'CO' | ||||||
|  |         ), | ||||||
|  |         departamento = fe.nomina.Departamento( | ||||||
|  |             code = '05' | ||||||
|  |         ), | ||||||
|  |         municipio = fe.nomina.Municipio( | ||||||
|  |             code = '05001' | ||||||
|  |         ), | ||||||
|  |         direccion = 'calle etrivial' | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_trabajador(fe.nomina.Trabajador( | ||||||
|  |         tipo_contrato = fe.nomina.TipoContrato( | ||||||
|  |             code = '1' | ||||||
|  |         ), | ||||||
|  |         alto_riesgo = False, | ||||||
|  |         tipo_documento = fe.nomina.TipoDocumento( | ||||||
|  |             code = '11' | ||||||
|  |         ), | ||||||
|  |         primer_apellido = 'GONZALEZ', | ||||||
|  |         segundo_apellido = '', | ||||||
|  |         primer_nombre = 'JUAN', | ||||||
|  |         lugar_trabajo = fe.nomina.LugarTrabajo( | ||||||
|  |             pais = fe.nomina.Pais(code='CO'), | ||||||
|  |             departamento = fe.nomina.Departamento(code='05'), | ||||||
|  |             municipio = fe.nomina.Municipio(code='05001'), | ||||||
|  |             direccion = 'CL 35C 102-17 BL 7 AP 101' | ||||||
|  |         ), | ||||||
|  |         numero_documento = NIT, | ||||||
|  |         tipo = fe.nomina.TipoTrabajador( | ||||||
|  |             code = '01' | ||||||
|  |         ), | ||||||
|  |         salario_integral = False, | ||||||
|  |         sueldo = fe.nomina.Amount(2400000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_devengado(fe.nomina.DevengadoBasico( | ||||||
|  |         dias_trabajados = 30, | ||||||
|  |         sueldo_trabajado = fe.nomina.Amount(2400000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_deduccion(fe.nomina.DeduccionSalud( | ||||||
|  |         porcentaje = fe.nomina.Amount(4), | ||||||
|  |         deduccion = fe.nomina.Amount(96000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_deduccion(fe.nomina.DeduccionFondoPension( | ||||||
|  |         porcentaje=fe.nomina.Amount(4), | ||||||
|  |         deduccion = fe.nomina.Amount(96000) | ||||||
|  |     )) | ||||||
|  |     return nomina | ||||||
|  |      | ||||||
							
								
								
									
										89
									
								
								examples/habilitacion/N000001.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								examples/habilitacion/N000001.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | <?xml version='1.0' encoding='UTF-8'?> | ||||||
|  | <NominaIndividual xmlns:atd="urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2" xmlns="dian:gov:co:facturaelectronica:NominaIndividual" xmlns:fe="http://www.dian.gov.co/contratos/facturaelectronica/v1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cdt="urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1" xmlns:clm54217="urn:un:unece:uncefact:codelist:specification:54217:2001" xmlns:clmIANAMIMEMediaType="urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:sts="dian:gov:co:facturaelectronica:Structures-2-1" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:sig="http://www.w3.org/2000/09/xmldsig#" SchemaLocation="" xsi:schemaLocation="dian:gov:co:facturaelectronica:NominaIndividual NominaIndividualElectronicaXSD.xsd"><ext:UBLExtensions><ext:UBLExtension><ext:ExtensionContent><ds:Signature Id="xmlsig-2e62ccd5-82d2-4922-90a0-31af30fc44c0"> | ||||||
|  | <ds:SignedInfo> | ||||||
|  | <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> | ||||||
|  | <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> | ||||||
|  | <ds:Reference Id="xmldsig-2e62ccd5-82d2-4922-90a0-31af30fc44c0-ref0" URI=""> | ||||||
|  | <ds:Transforms> | ||||||
|  | <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> | ||||||
|  | </ds:Transforms> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>HS3rmJgPKyCNLNO3TXfP0s1zIGvJTjq40JfMm/muHLA=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | <ds:Reference Id="xmldsig-2e62ccd5-82d2-4922-90a0-31af30fc44c0-ref1" URI="#xmldsig-2e62ccd5-82d2-4922-90a0-31af30fc44c0-KeyInfo"> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>88R+0zjb6NIUiHhT8EE1ale8bO+TR6SSQBtVQUYkZ6c=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | <ds:Reference URI="#xmldsig-2e62ccd5-82d2-4922-90a0-31af30fc44c0-signedprops" Type="http://uri.etsi.org/01903#SignedProperties"> | ||||||
|  | <ds:Transforms> | ||||||
|  | <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> | ||||||
|  | </ds:Transforms> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>QF0d+RznylwnbFaGclqPWLndUo35HVDouEYoS1wfVO8=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | </ds:SignedInfo> | ||||||
|  | <ds:SignatureValue>0JBFsBhyo4r/9m5vuBXbKirHOgniDNeGW3RNXpCE/sgXvrV3E4K8/M4HeO0VYtM0 | ||||||
|  | G4bHvvkP2NCkdrKgZ9gB+XG8E/rEmJnwKpHm2kaNnpM1pYGoqBNWpqCa5FnUsEk4 | ||||||
|  | c4BmBaKjmBSUrz+2JoOg1RKaaJumqGWm83IjWWJq9b4l40imL0XIgoTmWUtIGOA0 | ||||||
|  | swm5rokLFldHv9T9CQvuYqCQIb6GAb2HB/GzNcPVO6quCqNVI6K9+Zh6vNpWpnCW | ||||||
|  | crP8iCn4T3jo2PxU56dwA63xOtkTdYWphaGL4J63flsZysPQ817uuHV/XLu1VwHE | ||||||
|  | cBpcTWyXL9LB7rgqrVSIzw==</ds:SignatureValue> | ||||||
|  | <ds:KeyInfo Id="xmldsig-2e62ccd5-82d2-4922-90a0-31af30fc44c0-KeyInfo"> | ||||||
|  | <ds:X509Data> | ||||||
|  | <ds:X509Certificate>MIIH8TCCBdmgAwIBAgIIQxaPJd4YTlMwDQYJKoZIhvcNAQELBQAwgbYxIzAhBgkq | ||||||
|  | hkiG9w0BCQEWFGluZm9AYW5kZXNzY2QuY29tLmNvMSYwJAYDVQQDEx1DQSBBTkRF | ||||||
|  | UyBTQ0QgUy5BLiBDbGFzZSBJSSB2MzEwMC4GA1UECxMnRGl2aXNpb24gZGUgY2Vy | ||||||
|  | dGlmaWNhY2lvbiBlbnRpZGFkIGZpbmFsMRIwEAYDVQQKEwlBbmRlcyBTQ0QxFDAS | ||||||
|  | BgNVBAcTC0JvZ290YSBELkMuMQswCQYDVQQGEwJDTzAeFw0yNDA1MTYwNTAwMDBa | ||||||
|  | Fw0yNTA1MTYwNDU5MDBaMIIBQDEtMCsGA1UECRMkVFYgNDYgQyA0MiBFU1RFIDc4 | ||||||
|  | OSBDT1JSIFNBTlRBIEVMRU5BMSIwIAYJKoZIhvcNAQkBFhNiaWNpcGl6emFAZ21h | ||||||
|  | aWwuY29tMRowGAYDVQQDExFCSUNJIFBJWlpBIFMuQS5TLjETMBEGA1UEBRMKOTAx | ||||||
|  | NTc1NTI4MjE2MDQGA1UEDBMtRW1pc29yIEZhY3R1cmEgRWxlY3Ryb25pY2EgLSBQ | ||||||
|  | ZXJzb25hIEp1cmlkaWNhMTswOQYDVQQLEzJFbWl0aWRvIHBvciBBbmRlcyBTQ0Qg | ||||||
|  | QWMgMjYgNjkgQyAwMyBUb3JyZSBCIE9mIDcwMTEQMA4GA1UEChMHR0VSRU5URTES | ||||||
|  | MBAGA1UEBwwJTUVERUxMw41OMRIwEAYDVQQIEwlBTlRJT1FVSUExCzAJBgNVBAYT | ||||||
|  | AkNPMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5J1O+4ZedrSBUsb+ | ||||||
|  | 9tjNPHI9RGeIJcJl3Wc/208OqMYcCwGLUkrYBgH78E7IayD5/wra04OU57cS1/+/ | ||||||
|  | yBUWYR60oqkaH2/8OXkJMqmjisVM/b58m7zyMw4TAF8N/PbswnrKukFU2acxISwT | ||||||
|  | Lu36HC4hshWw8bEGP54szvv1xnwqcOAWNBCxcBuc9k1JD+SIiqqPwHKh+6EDIoou | ||||||
|  | jo0H15w3rAxkHQRvYe6/IrpvH2sqJl1I3dLv0iqy9+d2l891KBA9Yebdw7m/+ufu | ||||||
|  | +eqs+0zKrwV6QLhRFmceHzEkPMTFepc2COGf80OUNbI6WWnspvDK97D8YG0MeifP | ||||||
|  | YveIPwIDAQABo4ICdDCCAnAwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBRA/iZp | ||||||
|  | RzInMtGsIcgu7M+N1TVo6DBvBggrBgEFBQcBAQRjMGEwNgYIKwYBBQUHMAKGKmh0 | ||||||
|  | dHA6Ly9jZXJ0cy5hbmRlc3NjZC5jb20uY28vQ2xhc2VJSXYzLmNydDAnBggrBgEF | ||||||
|  | BQcwAYYbaHR0cDovL29jc3AuYW5kZXNzY2QuY29tLmNvMB4GA1UdEQQXMBWBE2Jp | ||||||
|  | Y2lwaXp6YUBnbWFpbC5jb20wggEjBgNVHSAEggEaMIIBFjCBwQYNKwYBBAGB9EgB | ||||||
|  | AgYIADCBrzCBrAYIKwYBBQUHAgIwgZ8MgZxMYSB1dGlsaXphY2nDs24gZGUgZXN0 | ||||||
|  | ZSBjZXJ0aWZpY2FkbyBlc3TDoSBzdWpldGEgYSBsYSBQQyBkZSBGYWN0dXJhY2nD | ||||||
|  | s24gRWxlY3Ryw7NuaWNhIHkgRFBDIGVzdGFibGVjaWRhcyBwb3IgQW5kZXMgU0NE | ||||||
|  | LiBDw7NkaWdvIGRlIEFjcmVkaXRhY2nDs246IDE2LUVDRC0wMDQwUAYNKwYBBAGB | ||||||
|  | 9EgBAQEKADA/MD0GCCsGAQUFBwIBFjFodHRwczovL3d3dy5hbmRlc3NjZC5jb20u | ||||||
|  | Y28vZG9jcy9EUENfQW5kZXNTQ0QucGRmMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr | ||||||
|  | BgEFBQcDBDA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLmFuZGVzc2NkLmNv | ||||||
|  | bS5jby9DbGFzZUlJdjMuY3JsMB0GA1UdDgQWBBRKPoh3BJM7SxEL0UXkSne2MyFO | ||||||
|  | jjAOBgNVHQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQELBQADggIBAA6Zzor3kpJ6vNKv | ||||||
|  | TAeHaMfmJ/PaghQ1+Lab7Pwk+lsPsMETFu/IpEK5qij2bV54UNnqyLYOZtIbnWTG | ||||||
|  | qgT7QxQvy+/of/I3zzF+kH4/Lp2TSlHaDEb/airCZ3I2G23M9iaZzSwYuOsOaGwp | ||||||
|  | 4ovkXlYwQ7FVNfIIoAq95m9cBAigb06bRIlVBVTQq44hQFQQG6aSIT7SSPtCwPhB | ||||||
|  | 5CJzG09pmgbxizqN/yxdjWdfW6Av79dh6K4uQT++Vtyp5DuAkmfn0ehayrUbDLkH | ||||||
|  | 9jQFF128U5pnOPfKWf22acXqQBapesUSV/HZUZ3PXoWeHWXcMdz0azxOEunS4+px | ||||||
|  | fs5UzInRAmEcYwJHqJT3irFz+J2RsZ0WnJHrTGqFoXniQQH8QbCHehDTGN7/v/v1 | ||||||
|  | LQBr5PQBnSEWhmrQ9uFrwPyMMg3yd+L75TaHLZ0MTSVezAG52oM9jBiU5tYXkSio | ||||||
|  | EfPdIsGlG74BybULGSG2OlTINlblj/lj7pL67V+gY9EGN1zzNKL5sW4YXlXewa6K | ||||||
|  | dTpLmmzWzI8Cm+tOuuJDSHSwMjn525O+Z/oyKLjdQdyfg1KnZYwNZFpMmCwfP5nd | ||||||
|  | cm4F7Anzb9HX9ciluAxc6as9TsNoDDTSAGPuUr0QvXqXd9ZCgXdNzdFeiaYknLP5 | ||||||
|  | hT4f5CoO2M8qcG+CH7HnkaOHrSuK</ds:X509Certificate> | ||||||
|  | </ds:X509Data> | ||||||
|  | <ds:KeyValue> | ||||||
|  | <ds:RSAKeyValue> | ||||||
|  | <ds:Modulus>5J1O+4ZedrSBUsb+9tjNPHI9RGeIJcJl3Wc/208OqMYcCwGLUkrYBgH78E7IayD5 | ||||||
|  | /wra04OU57cS1/+/yBUWYR60oqkaH2/8OXkJMqmjisVM/b58m7zyMw4TAF8N/Pbs | ||||||
|  | wnrKukFU2acxISwTLu36HC4hshWw8bEGP54szvv1xnwqcOAWNBCxcBuc9k1JD+SI | ||||||
|  | iqqPwHKh+6EDIooujo0H15w3rAxkHQRvYe6/IrpvH2sqJl1I3dLv0iqy9+d2l891 | ||||||
|  | KBA9Yebdw7m/+ufu+eqs+0zKrwV6QLhRFmceHzEkPMTFepc2COGf80OUNbI6WWns | ||||||
|  | pvDK97D8YG0MeifPYveIPw==</ds:Modulus> | ||||||
|  | <ds:Exponent>AQAB</ds:Exponent> | ||||||
|  | </ds:RSAKeyValue> | ||||||
|  | </ds:KeyValue> | ||||||
|  | </ds:KeyInfo> | ||||||
|  | <ds:Object><xades:QualifyingProperties Target="#xmlsig-2e62ccd5-82d2-4922-90a0-31af30fc44c0" Id="XadesObjects"><xades:SignedProperties Id="xmldsig-2e62ccd5-82d2-4922-90a0-31af30fc44c0-signedprops"><xades:SignedSignatureProperties><xades:SigningTime>2025-03-16T16:49:57.777363</xades:SigningTime><xades:SigningCertificate><xades:Cert><xades:CertDigest><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>YcIPspAVFcNg+B/galYrdCLYvLIEwFI4KWdSzcuupPY=</ds:DigestValue></xades:CertDigest><xades:IssuerSerial><ds:X509IssuerName>C=CO, L=Bogota D.C., O=Andes SCD, OU=Division de certificacion entidad final, CN=CA ANDES SCD S.A. Clase II v3, OID.1.2.840.113549.1.9.1=info@andesscd.com.co</ds:X509IssuerName><ds:X509SerialNumber>4834208642831502931</ds:X509SerialNumber></xades:IssuerSerial></xades:Cert></xades:SigningCertificate><xades:SignaturePolicyIdentifier><xades:SignaturePolicyId><xades:SigPolicyId><xades:Identifier>https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf</xades:Identifier><xades:Description>Política de firma para facturas electrónicas de la República de Colombia.</xades:Description></xades:SigPolicyId><xades:SigPolicyHash><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>dMoMvtcG5aIzgYo0tIsSQeVJBDnUnfSOfBpxXrmor0Y=</ds:DigestValue></xades:SigPolicyHash></xades:SignaturePolicyId></xades:SignaturePolicyIdentifier><xades:SignerRole><xades:ClaimedRoles><xades:ClaimedRole>supplier</xades:ClaimedRole></xades:ClaimedRoles></xades:SignerRole></xades:SignedSignatureProperties></xades:SignedProperties></xades:QualifyingProperties></ds:Object></ds:Signature></ext:ExtensionContent></ext:UBLExtension></ext:UBLExtensions><Novedad CUNENov="false">false</Novedad><Periodo FechaIngreso="2022-01-05" FechaLiquidacionInicio="2024-04-01" FechaLiquidacionFin="2024-04-30" TiempoLaborado="1" FechaGen="2024-04-30"/><NumeroSecuenciaXML Prefijo="N" Consecutivo="000001" Numero="N000001"/><LugarGeneracionXML Pais="CO" DepartamentoEstado="05" MunicipioCiudad="05001" Idioma="es"/><ProveedorXML NIT="901575528" DV="2" SoftwareID="100b0d10-0ca0-4ad4-a894-b704a568cbf3" RazonSocial="BICI PIZZA S.A.S" SoftwareSC="277c710304542320e15609646371219dc9ac3edd9c73adc0a278a355fbef97609bb7e451b92900b517044443f6ae1838"/><CodigoQR>https://catalogo-vpfe-hab.dian.gov.co/document/searchqr?documentkey=f498037db4d2f7c42224fbdc958d031927f17f0ad4e4c1f4a3e85d6363d68f3f951860873e6899937c080f03b0bd0ceb</CodigoQR><InformacionGeneral Version="V1.0: Documento Soporte de Pago de Nómina Electrónica" Ambiente="2" TipoXML="102" EncripCUNE="CUNE-SHA384" FechaGen="2024-04-30" HoraGen="08:01:00-05:00" PeriodoNomina="1" TipoMoneda="COP" TRM="0" CUNE="f498037db4d2f7c42224fbdc958d031927f17f0ad4e4c1f4a3e85d6363d68f3f951860873e6899937c080f03b0bd0ceb"/><Empleador NIT="901575528" DV="2" Pais="CO" DepartamentoEstado="05" MunicipioCiudad="05001" Direccion="calle etrivial" RazonSocial="BICI PIZZA S.A.S"/><Trabajador TipoTrabajador="01" SubTipoTrabajador="00" AltoRiesgoPension="false" TipoDocumento="11" NumeroDocumento="901575528" PrimerApellido="GONZALEZ" SegundoApellido="" PrimerNombre="JUAN" LugarTrabajoPais="CO" LugarTrabajoDepartamentoEstado="05" LugarTrabajoMunicipioCiudad="05001" LugarTrabajoDireccion="CL 35C 102-17 BL 7 AP 101" SalarioIntegral="false" TipoContrato="1" Sueldo="2400000.0"/><Pago Forma="1" Metodo="10"/><FechasPagos><FechaPago>2024-04-30</FechaPago></FechasPagos><Devengados><Basico DiasTrabajados="30" SueldoTrabajado="2400000.00"/></Devengados><Deducciones><Salud Porcentaje="4.00" Deduccion="96000.0"/><FondoPension Porcentaje="4.00" Deduccion="96000.0"/></Deducciones><Redondeo>0</Redondeo><DevengadosTotal>2400000.00</DevengadosTotal><DeduccionesTotal>192000.00</DeduccionesTotal><ComprobanteTotal>2208000.00</ComprobanteTotal></NominaIndividual> | ||||||
							
								
								
									
										
											BIN
										
									
								
								examples/habilitacion/N000001.zip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								examples/habilitacion/N000001.zip
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										123
									
								
								examples/habilitacion/N000002.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								examples/habilitacion/N000002.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  |  | ||||||
|  | from facho import fe | ||||||
|  |  | ||||||
|  | SOFTWARE_PIN='20234' | ||||||
|  | SOFTWARE_ID='100b0d10-0ca0-4ad4-a894-b704a568cbf3' | ||||||
|  | NIT='901575528' | ||||||
|  | DV='2' | ||||||
|  |  | ||||||
|  | def extensions(nomina): | ||||||
|  |     return [] | ||||||
|  |  | ||||||
|  | def nomina(): | ||||||
|  |     nomina = fe.nomina.DIANNominaIndividual() | ||||||
|  |  | ||||||
|  |     nomina.asignar_fecha_pago('2024-04-30') | ||||||
|  |  | ||||||
|  |     nomina.asignar_metadata(fe.nomina.Metadata( | ||||||
|  |     novedad=fe.nomina.Novedad(value='false'), | ||||||
|  |         secuencia=fe.nomina.NumeroSecuencia( | ||||||
|  |             prefijo='N', | ||||||
|  |             consecutivo='000002' | ||||||
|  |         ), | ||||||
|  |         lugar_generacion=fe.nomina.Lugar( | ||||||
|  |             pais = fe.nomina.Pais( | ||||||
|  |                 code = 'CO' | ||||||
|  |             ), | ||||||
|  |             departamento = fe.nomina.Departamento( | ||||||
|  |                 code = '05' | ||||||
|  |             ), | ||||||
|  |             municipio = fe.nomina.Municipio( | ||||||
|  |                 code = '05001' | ||||||
|  |             ), | ||||||
|  |         ), | ||||||
|  |         proveedor=fe.nomina.Proveedor( | ||||||
|  | 	    razon_social='BICI PIZZA S.A.S', | ||||||
|  |             nit=NIT, | ||||||
|  |             dv=DV, | ||||||
|  |             software_id=SOFTWARE_ID, | ||||||
|  |             software_pin=SOFTWARE_PIN | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_periodo(fe.nomina.Periodo( | ||||||
|  |         fecha_ingreso= '2022-09-05', | ||||||
|  |         fecha_liquidacion_inicio='2024-04-01', | ||||||
|  |         fecha_liquidacion_fin='2024-04-30', | ||||||
|  |         fecha_generacion='2024-04-30' | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_informacion_general(fe.nomina.InformacionGeneral( | ||||||
|  |         fecha_generacion = '2024-04-30', | ||||||
|  |         hora_generacion = '08:01:00-05:00', | ||||||
|  |         tipo_ambiente = fe.nomina.InformacionGeneral.AMBIENTE_PRUEBAS, | ||||||
|  |         software_pin = SOFTWARE_PIN, | ||||||
|  |         periodo_nomina = fe.nomina.PeriodoNomina(code='1'), | ||||||
|  |         tipo_moneda = fe.nomina.TipoMoneda(code='COP') | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_pago(fe.nomina.Pago( | ||||||
|  |         forma=fe.nomina.FormaPago( | ||||||
|  |             code='1', | ||||||
|  |         ), | ||||||
|  |         metodo=fe.nomina.MetodoPago( | ||||||
|  |             code='10' | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |     nomina.asignar_empleador(fe.nomina.Empleador( | ||||||
|  | 	razon_social='BICI PIZZA S.A.S', | ||||||
|  |         nit = NIT, | ||||||
|  |         dv = DV, | ||||||
|  |         pais = fe.nomina.Pais( | ||||||
|  |             code = 'CO' | ||||||
|  |         ), | ||||||
|  |         departamento = fe.nomina.Departamento( | ||||||
|  |             code = '05' | ||||||
|  |         ), | ||||||
|  |         municipio = fe.nomina.Municipio( | ||||||
|  |             code = '05001' | ||||||
|  |         ), | ||||||
|  |         direccion = 'calle etrivial' | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_trabajador(fe.nomina.Trabajador( | ||||||
|  |         tipo_contrato = fe.nomina.TipoContrato( | ||||||
|  |             code = '1' | ||||||
|  |         ), | ||||||
|  |         alto_riesgo = False, | ||||||
|  |         tipo_documento = fe.nomina.TipoDocumento( | ||||||
|  |             code = '11' | ||||||
|  |         ), | ||||||
|  |         primer_apellido = 'GIRALDO', | ||||||
|  |         segundo_apellido = '', | ||||||
|  |         primer_nombre = 'VIVIANA', | ||||||
|  |         lugar_trabajo = fe.nomina.LugarTrabajo( | ||||||
|  |             pais = fe.nomina.Pais(code='CO'), | ||||||
|  |             departamento = fe.nomina.Departamento(code='05'), | ||||||
|  |             municipio = fe.nomina.Municipio(code='05001'), | ||||||
|  |             direccion = 'CL 35C 102-17 BL 7 AP 101' | ||||||
|  |         ), | ||||||
|  |         numero_documento = NIT, | ||||||
|  |         tipo = fe.nomina.TipoTrabajador( | ||||||
|  |             code = '01' | ||||||
|  |         ), | ||||||
|  |         salario_integral = False, | ||||||
|  |         sueldo = fe.nomina.Amount(1160000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_devengado(fe.nomina.DevengadoBasico( | ||||||
|  |         dias_trabajados = 30, | ||||||
|  |         sueldo_trabajado = fe.nomina.Amount(1160000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_deduccion(fe.nomina.DeduccionSalud( | ||||||
|  |         porcentaje = fe.nomina.Amount(4), | ||||||
|  |         deduccion = fe.nomina.Amount(46400) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_deduccion(fe.nomina.DeduccionFondoPension( | ||||||
|  |         porcentaje=fe.nomina.Amount(4), | ||||||
|  |         deduccion = fe.nomina.Amount(46400) | ||||||
|  |     )) | ||||||
|  |     return nomina | ||||||
|  |      | ||||||
							
								
								
									
										89
									
								
								examples/habilitacion/N000002.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								examples/habilitacion/N000002.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | <?xml version='1.0' encoding='UTF-8'?> | ||||||
|  | <NominaIndividual xmlns:atd="urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2" xmlns="dian:gov:co:facturaelectronica:NominaIndividual" xmlns:fe="http://www.dian.gov.co/contratos/facturaelectronica/v1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cdt="urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1" xmlns:clm54217="urn:un:unece:uncefact:codelist:specification:54217:2001" xmlns:clmIANAMIMEMediaType="urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:sts="dian:gov:co:facturaelectronica:Structures-2-1" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:sig="http://www.w3.org/2000/09/xmldsig#" SchemaLocation="" xsi:schemaLocation="dian:gov:co:facturaelectronica:NominaIndividual NominaIndividualElectronicaXSD.xsd"><ext:UBLExtensions><ext:UBLExtension><ext:ExtensionContent><ds:Signature Id="xmlsig-bd7246f2-0f63-4a0a-822b-f59be349b7df"> | ||||||
|  | <ds:SignedInfo> | ||||||
|  | <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> | ||||||
|  | <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> | ||||||
|  | <ds:Reference Id="xmldsig-bd7246f2-0f63-4a0a-822b-f59be349b7df-ref0" URI=""> | ||||||
|  | <ds:Transforms> | ||||||
|  | <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> | ||||||
|  | </ds:Transforms> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>OZ66ZARE1QPKfYYk+BdiEnO0675e7p00fGwhb/Iyd5s=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | <ds:Reference Id="xmldsig-bd7246f2-0f63-4a0a-822b-f59be349b7df-ref1" URI="#xmldsig-bd7246f2-0f63-4a0a-822b-f59be349b7df-KeyInfo"> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>jZRqaYdQrLDYoqJmrKrLoO2ZHlGX1Xo5IpGFAznaQnI=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | <ds:Reference URI="#xmldsig-bd7246f2-0f63-4a0a-822b-f59be349b7df-signedprops" Type="http://uri.etsi.org/01903#SignedProperties"> | ||||||
|  | <ds:Transforms> | ||||||
|  | <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> | ||||||
|  | </ds:Transforms> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>XNMT1fgTLgeuUDfYH//8aY/TqzhsRcScSySL/6nKwxE=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | </ds:SignedInfo> | ||||||
|  | <ds:SignatureValue>fHBH/GVqHYi8iFbtTUwLUaVerZjfoj64Toq5jE+qi/HLmwhtDCAK2V/ISn0VDxpJ | ||||||
|  | 3QrAqWw/VjTFEqWmRV7mCxybM98A/+5yeWbvDkG2eY5fUOUHin9+oomysY8cwLjA | ||||||
|  | joXsvjEJlM1YIndzWG/Dryr14Hcax6ItVSaopA+1BpUoFn/5jWwZXsbmq0jHDjsI | ||||||
|  | Vyk1WpZzYwmM/aGZg7gj/pR7kZZOnv4d3L/MnFP6vJRdRNtRwO73wBd5lYGU1KaB | ||||||
|  | iTimrV2gBwg0+o5bqloSaQEtqV87adJG0h3eosSiIhrG9rc9rOpvqqq7tG2nAxRx | ||||||
|  | NyPM8gwuKoaoU9ogvRsqHQ==</ds:SignatureValue> | ||||||
|  | <ds:KeyInfo Id="xmldsig-bd7246f2-0f63-4a0a-822b-f59be349b7df-KeyInfo"> | ||||||
|  | <ds:X509Data> | ||||||
|  | <ds:X509Certificate>MIIH8TCCBdmgAwIBAgIIQxaPJd4YTlMwDQYJKoZIhvcNAQELBQAwgbYxIzAhBgkq | ||||||
|  | hkiG9w0BCQEWFGluZm9AYW5kZXNzY2QuY29tLmNvMSYwJAYDVQQDEx1DQSBBTkRF | ||||||
|  | UyBTQ0QgUy5BLiBDbGFzZSBJSSB2MzEwMC4GA1UECxMnRGl2aXNpb24gZGUgY2Vy | ||||||
|  | dGlmaWNhY2lvbiBlbnRpZGFkIGZpbmFsMRIwEAYDVQQKEwlBbmRlcyBTQ0QxFDAS | ||||||
|  | BgNVBAcTC0JvZ290YSBELkMuMQswCQYDVQQGEwJDTzAeFw0yNDA1MTYwNTAwMDBa | ||||||
|  | Fw0yNTA1MTYwNDU5MDBaMIIBQDEtMCsGA1UECRMkVFYgNDYgQyA0MiBFU1RFIDc4 | ||||||
|  | OSBDT1JSIFNBTlRBIEVMRU5BMSIwIAYJKoZIhvcNAQkBFhNiaWNpcGl6emFAZ21h | ||||||
|  | aWwuY29tMRowGAYDVQQDExFCSUNJIFBJWlpBIFMuQS5TLjETMBEGA1UEBRMKOTAx | ||||||
|  | NTc1NTI4MjE2MDQGA1UEDBMtRW1pc29yIEZhY3R1cmEgRWxlY3Ryb25pY2EgLSBQ | ||||||
|  | ZXJzb25hIEp1cmlkaWNhMTswOQYDVQQLEzJFbWl0aWRvIHBvciBBbmRlcyBTQ0Qg | ||||||
|  | QWMgMjYgNjkgQyAwMyBUb3JyZSBCIE9mIDcwMTEQMA4GA1UEChMHR0VSRU5URTES | ||||||
|  | MBAGA1UEBwwJTUVERUxMw41OMRIwEAYDVQQIEwlBTlRJT1FVSUExCzAJBgNVBAYT | ||||||
|  | AkNPMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5J1O+4ZedrSBUsb+ | ||||||
|  | 9tjNPHI9RGeIJcJl3Wc/208OqMYcCwGLUkrYBgH78E7IayD5/wra04OU57cS1/+/ | ||||||
|  | yBUWYR60oqkaH2/8OXkJMqmjisVM/b58m7zyMw4TAF8N/PbswnrKukFU2acxISwT | ||||||
|  | Lu36HC4hshWw8bEGP54szvv1xnwqcOAWNBCxcBuc9k1JD+SIiqqPwHKh+6EDIoou | ||||||
|  | jo0H15w3rAxkHQRvYe6/IrpvH2sqJl1I3dLv0iqy9+d2l891KBA9Yebdw7m/+ufu | ||||||
|  | +eqs+0zKrwV6QLhRFmceHzEkPMTFepc2COGf80OUNbI6WWnspvDK97D8YG0MeifP | ||||||
|  | YveIPwIDAQABo4ICdDCCAnAwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBRA/iZp | ||||||
|  | RzInMtGsIcgu7M+N1TVo6DBvBggrBgEFBQcBAQRjMGEwNgYIKwYBBQUHMAKGKmh0 | ||||||
|  | dHA6Ly9jZXJ0cy5hbmRlc3NjZC5jb20uY28vQ2xhc2VJSXYzLmNydDAnBggrBgEF | ||||||
|  | BQcwAYYbaHR0cDovL29jc3AuYW5kZXNzY2QuY29tLmNvMB4GA1UdEQQXMBWBE2Jp | ||||||
|  | Y2lwaXp6YUBnbWFpbC5jb20wggEjBgNVHSAEggEaMIIBFjCBwQYNKwYBBAGB9EgB | ||||||
|  | AgYIADCBrzCBrAYIKwYBBQUHAgIwgZ8MgZxMYSB1dGlsaXphY2nDs24gZGUgZXN0 | ||||||
|  | ZSBjZXJ0aWZpY2FkbyBlc3TDoSBzdWpldGEgYSBsYSBQQyBkZSBGYWN0dXJhY2nD | ||||||
|  | s24gRWxlY3Ryw7NuaWNhIHkgRFBDIGVzdGFibGVjaWRhcyBwb3IgQW5kZXMgU0NE | ||||||
|  | LiBDw7NkaWdvIGRlIEFjcmVkaXRhY2nDs246IDE2LUVDRC0wMDQwUAYNKwYBBAGB | ||||||
|  | 9EgBAQEKADA/MD0GCCsGAQUFBwIBFjFodHRwczovL3d3dy5hbmRlc3NjZC5jb20u | ||||||
|  | Y28vZG9jcy9EUENfQW5kZXNTQ0QucGRmMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr | ||||||
|  | BgEFBQcDBDA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLmFuZGVzc2NkLmNv | ||||||
|  | bS5jby9DbGFzZUlJdjMuY3JsMB0GA1UdDgQWBBRKPoh3BJM7SxEL0UXkSne2MyFO | ||||||
|  | jjAOBgNVHQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQELBQADggIBAA6Zzor3kpJ6vNKv | ||||||
|  | TAeHaMfmJ/PaghQ1+Lab7Pwk+lsPsMETFu/IpEK5qij2bV54UNnqyLYOZtIbnWTG | ||||||
|  | qgT7QxQvy+/of/I3zzF+kH4/Lp2TSlHaDEb/airCZ3I2G23M9iaZzSwYuOsOaGwp | ||||||
|  | 4ovkXlYwQ7FVNfIIoAq95m9cBAigb06bRIlVBVTQq44hQFQQG6aSIT7SSPtCwPhB | ||||||
|  | 5CJzG09pmgbxizqN/yxdjWdfW6Av79dh6K4uQT++Vtyp5DuAkmfn0ehayrUbDLkH | ||||||
|  | 9jQFF128U5pnOPfKWf22acXqQBapesUSV/HZUZ3PXoWeHWXcMdz0azxOEunS4+px | ||||||
|  | fs5UzInRAmEcYwJHqJT3irFz+J2RsZ0WnJHrTGqFoXniQQH8QbCHehDTGN7/v/v1 | ||||||
|  | LQBr5PQBnSEWhmrQ9uFrwPyMMg3yd+L75TaHLZ0MTSVezAG52oM9jBiU5tYXkSio | ||||||
|  | EfPdIsGlG74BybULGSG2OlTINlblj/lj7pL67V+gY9EGN1zzNKL5sW4YXlXewa6K | ||||||
|  | dTpLmmzWzI8Cm+tOuuJDSHSwMjn525O+Z/oyKLjdQdyfg1KnZYwNZFpMmCwfP5nd | ||||||
|  | cm4F7Anzb9HX9ciluAxc6as9TsNoDDTSAGPuUr0QvXqXd9ZCgXdNzdFeiaYknLP5 | ||||||
|  | hT4f5CoO2M8qcG+CH7HnkaOHrSuK</ds:X509Certificate> | ||||||
|  | </ds:X509Data> | ||||||
|  | <ds:KeyValue> | ||||||
|  | <ds:RSAKeyValue> | ||||||
|  | <ds:Modulus>5J1O+4ZedrSBUsb+9tjNPHI9RGeIJcJl3Wc/208OqMYcCwGLUkrYBgH78E7IayD5 | ||||||
|  | /wra04OU57cS1/+/yBUWYR60oqkaH2/8OXkJMqmjisVM/b58m7zyMw4TAF8N/Pbs | ||||||
|  | wnrKukFU2acxISwTLu36HC4hshWw8bEGP54szvv1xnwqcOAWNBCxcBuc9k1JD+SI | ||||||
|  | iqqPwHKh+6EDIooujo0H15w3rAxkHQRvYe6/IrpvH2sqJl1I3dLv0iqy9+d2l891 | ||||||
|  | KBA9Yebdw7m/+ufu+eqs+0zKrwV6QLhRFmceHzEkPMTFepc2COGf80OUNbI6WWns | ||||||
|  | pvDK97D8YG0MeifPYveIPw==</ds:Modulus> | ||||||
|  | <ds:Exponent>AQAB</ds:Exponent> | ||||||
|  | </ds:RSAKeyValue> | ||||||
|  | </ds:KeyValue> | ||||||
|  | </ds:KeyInfo> | ||||||
|  | <ds:Object><xades:QualifyingProperties Target="#xmlsig-bd7246f2-0f63-4a0a-822b-f59be349b7df" Id="XadesObjects"><xades:SignedProperties Id="xmldsig-bd7246f2-0f63-4a0a-822b-f59be349b7df-signedprops"><xades:SignedSignatureProperties><xades:SigningTime>2025-03-16T16:50:01.250573</xades:SigningTime><xades:SigningCertificate><xades:Cert><xades:CertDigest><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>YcIPspAVFcNg+B/galYrdCLYvLIEwFI4KWdSzcuupPY=</ds:DigestValue></xades:CertDigest><xades:IssuerSerial><ds:X509IssuerName>C=CO, L=Bogota D.C., O=Andes SCD, OU=Division de certificacion entidad final, CN=CA ANDES SCD S.A. Clase II v3, OID.1.2.840.113549.1.9.1=info@andesscd.com.co</ds:X509IssuerName><ds:X509SerialNumber>4834208642831502931</ds:X509SerialNumber></xades:IssuerSerial></xades:Cert></xades:SigningCertificate><xades:SignaturePolicyIdentifier><xades:SignaturePolicyId><xades:SigPolicyId><xades:Identifier>https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf</xades:Identifier><xades:Description>Política de firma para facturas electrónicas de la República de Colombia.</xades:Description></xades:SigPolicyId><xades:SigPolicyHash><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>dMoMvtcG5aIzgYo0tIsSQeVJBDnUnfSOfBpxXrmor0Y=</ds:DigestValue></xades:SigPolicyHash></xades:SignaturePolicyId></xades:SignaturePolicyIdentifier><xades:SignerRole><xades:ClaimedRoles><xades:ClaimedRole>supplier</xades:ClaimedRole></xades:ClaimedRoles></xades:SignerRole></xades:SignedSignatureProperties></xades:SignedProperties></xades:QualifyingProperties></ds:Object></ds:Signature></ext:ExtensionContent></ext:UBLExtension></ext:UBLExtensions><Novedad CUNENov="false">false</Novedad><Periodo FechaIngreso="2022-09-05" FechaLiquidacionInicio="2024-04-01" FechaLiquidacionFin="2024-04-30" TiempoLaborado="1" FechaGen="2024-04-30"/><NumeroSecuenciaXML Prefijo="N" Consecutivo="000002" Numero="N000002"/><LugarGeneracionXML Pais="CO" DepartamentoEstado="05" MunicipioCiudad="05001" Idioma="es"/><ProveedorXML NIT="901575528" DV="2" SoftwareID="100b0d10-0ca0-4ad4-a894-b704a568cbf3" RazonSocial="BICI PIZZA S.A.S" SoftwareSC="067c1069842576f1f954d3540d9f75a214e2a63219f36f4f25465e26958c10d2c9e222076635379bd7f61ca0459c87e9"/><CodigoQR>https://catalogo-vpfe-hab.dian.gov.co/document/searchqr?documentkey=cb2e6968a811c661ebdc8b8cd19a323ca05471c2fe3c3b1cfb5275379d7df94d6c22f9405d732295e805095e366a99fa</CodigoQR><InformacionGeneral Version="V1.0: Documento Soporte de Pago de Nómina Electrónica" Ambiente="2" TipoXML="102" EncripCUNE="CUNE-SHA384" FechaGen="2024-04-30" HoraGen="08:01:00-05:00" PeriodoNomina="1" TipoMoneda="COP" TRM="0" CUNE="cb2e6968a811c661ebdc8b8cd19a323ca05471c2fe3c3b1cfb5275379d7df94d6c22f9405d732295e805095e366a99fa"/><Empleador NIT="901575528" DV="2" Pais="CO" DepartamentoEstado="05" MunicipioCiudad="05001" Direccion="calle etrivial" RazonSocial="BICI PIZZA S.A.S"/><Trabajador TipoTrabajador="01" SubTipoTrabajador="00" AltoRiesgoPension="false" TipoDocumento="11" NumeroDocumento="901575528" PrimerApellido="GIRALDO" SegundoApellido="" PrimerNombre="VIVIANA" LugarTrabajoPais="CO" LugarTrabajoDepartamentoEstado="05" LugarTrabajoMunicipioCiudad="05001" LugarTrabajoDireccion="CL 35C 102-17 BL 7 AP 101" SalarioIntegral="false" TipoContrato="1" Sueldo="1160000.0"/><Pago Forma="1" Metodo="10"/><FechasPagos><FechaPago>2024-04-30</FechaPago></FechasPagos><Devengados><Basico DiasTrabajados="30" SueldoTrabajado="1160000.00"/></Devengados><Deducciones><Salud Porcentaje="4.00" Deduccion="46400.0"/><FondoPension Porcentaje="4.00" Deduccion="46400.0"/></Deducciones><Redondeo>0</Redondeo><DevengadosTotal>1160000.00</DevengadosTotal><DeduccionesTotal>92800.00</DeduccionesTotal><ComprobanteTotal>1067200.00</ComprobanteTotal></NominaIndividual> | ||||||
							
								
								
									
										
											BIN
										
									
								
								examples/habilitacion/N000002.zip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								examples/habilitacion/N000002.zip
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										123
									
								
								examples/habilitacion/N000003.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								examples/habilitacion/N000003.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  |  | ||||||
|  | from facho import fe | ||||||
|  |  | ||||||
|  | SOFTWARE_PIN='20234' | ||||||
|  | SOFTWARE_ID='100b0d10-0ca0-4ad4-a894-b704a568cbf3' | ||||||
|  | NIT='901575528' | ||||||
|  | DV='2' | ||||||
|  |  | ||||||
|  | def extensions(nomina): | ||||||
|  |     return [] | ||||||
|  |  | ||||||
|  | def nomina(): | ||||||
|  |     nomina = fe.nomina.DIANNominaIndividual() | ||||||
|  |  | ||||||
|  |     nomina.asignar_fecha_pago('2024-04-30') | ||||||
|  |  | ||||||
|  |     nomina.asignar_metadata(fe.nomina.Metadata( | ||||||
|  |     novedad=fe.nomina.Novedad(value='false'), | ||||||
|  |         secuencia=fe.nomina.NumeroSecuencia( | ||||||
|  |             prefijo='N', | ||||||
|  |             consecutivo='000003' | ||||||
|  |         ), | ||||||
|  |         lugar_generacion=fe.nomina.Lugar( | ||||||
|  |             pais = fe.nomina.Pais( | ||||||
|  |                 code = 'CO' | ||||||
|  |             ), | ||||||
|  |             departamento = fe.nomina.Departamento( | ||||||
|  |                 code = '05' | ||||||
|  |             ), | ||||||
|  |             municipio = fe.nomina.Municipio( | ||||||
|  |                 code = '05001' | ||||||
|  |             ), | ||||||
|  |         ), | ||||||
|  |         proveedor=fe.nomina.Proveedor( | ||||||
|  | 	    razon_social='BICI PIZZA S.A.S', | ||||||
|  |             nit=NIT, | ||||||
|  |             dv=DV, | ||||||
|  |             software_id=SOFTWARE_ID, | ||||||
|  |             software_pin=SOFTWARE_PIN | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_periodo(fe.nomina.Periodo( | ||||||
|  |         fecha_ingreso= '2022-01-05', | ||||||
|  |         fecha_liquidacion_inicio='2024-04-01', | ||||||
|  |         fecha_liquidacion_fin='2024-04-30', | ||||||
|  |         fecha_generacion='2024-04-30' | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_informacion_general(fe.nomina.InformacionGeneral( | ||||||
|  |         fecha_generacion = '2024-04-30', | ||||||
|  |         hora_generacion = '08:01:00-05:00', | ||||||
|  |         tipo_ambiente = fe.nomina.InformacionGeneral.AMBIENTE_PRUEBAS, | ||||||
|  |         software_pin = SOFTWARE_PIN, | ||||||
|  |         periodo_nomina = fe.nomina.PeriodoNomina(code='1'), | ||||||
|  |         tipo_moneda = fe.nomina.TipoMoneda(code='COP') | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_pago(fe.nomina.Pago( | ||||||
|  |         forma=fe.nomina.FormaPago( | ||||||
|  |             code='1', | ||||||
|  |         ), | ||||||
|  |         metodo=fe.nomina.MetodoPago( | ||||||
|  |             code='10' | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |     nomina.asignar_empleador(fe.nomina.Empleador( | ||||||
|  | 	razon_social='BICI PIZZA S.A.S', | ||||||
|  |         nit = NIT, | ||||||
|  |         dv = DV, | ||||||
|  |         pais = fe.nomina.Pais( | ||||||
|  |             code = 'CO' | ||||||
|  |         ), | ||||||
|  |         departamento = fe.nomina.Departamento( | ||||||
|  |             code = '05' | ||||||
|  |         ), | ||||||
|  |         municipio = fe.nomina.Municipio( | ||||||
|  |             code = '05001' | ||||||
|  |         ), | ||||||
|  |         direccion = 'calle etrivial' | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_trabajador(fe.nomina.Trabajador( | ||||||
|  |         tipo_contrato = fe.nomina.TipoContrato( | ||||||
|  |             code = '1' | ||||||
|  |         ), | ||||||
|  |         alto_riesgo = False, | ||||||
|  |         tipo_documento = fe.nomina.TipoDocumento( | ||||||
|  |             code = '11' | ||||||
|  |         ), | ||||||
|  |         primer_apellido = 'GONZALEZ', | ||||||
|  |         segundo_apellido = '', | ||||||
|  |         primer_nombre = 'JUAN', | ||||||
|  |         lugar_trabajo = fe.nomina.LugarTrabajo( | ||||||
|  |             pais = fe.nomina.Pais(code='CO'), | ||||||
|  |             departamento = fe.nomina.Departamento(code='05'), | ||||||
|  |             municipio = fe.nomina.Municipio(code='05001'), | ||||||
|  |             direccion = 'CL 35C 102-17 BL 7 AP 101' | ||||||
|  |         ), | ||||||
|  |         numero_documento = NIT, | ||||||
|  |         tipo = fe.nomina.TipoTrabajador( | ||||||
|  |             code = '01' | ||||||
|  |         ), | ||||||
|  |         salario_integral = False, | ||||||
|  |         sueldo = fe.nomina.Amount(2400000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_devengado(fe.nomina.DevengadoBasico( | ||||||
|  |         dias_trabajados = 30, | ||||||
|  |         sueldo_trabajado = fe.nomina.Amount(2400000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_deduccion(fe.nomina.DeduccionSalud( | ||||||
|  |         porcentaje = fe.nomina.Amount(4), | ||||||
|  |         deduccion = fe.nomina.Amount(96000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_deduccion(fe.nomina.DeduccionFondoPension( | ||||||
|  |         porcentaje=fe.nomina.Amount(4), | ||||||
|  |         deduccion = fe.nomina.Amount(96000) | ||||||
|  |     )) | ||||||
|  |     return nomina | ||||||
|  |      | ||||||
							
								
								
									
										89
									
								
								examples/habilitacion/N000003.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								examples/habilitacion/N000003.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | <?xml version='1.0' encoding='UTF-8'?> | ||||||
|  | <NominaIndividual xmlns:atd="urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2" xmlns="dian:gov:co:facturaelectronica:NominaIndividual" xmlns:fe="http://www.dian.gov.co/contratos/facturaelectronica/v1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cdt="urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1" xmlns:clm54217="urn:un:unece:uncefact:codelist:specification:54217:2001" xmlns:clmIANAMIMEMediaType="urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:sts="dian:gov:co:facturaelectronica:Structures-2-1" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:sig="http://www.w3.org/2000/09/xmldsig#" SchemaLocation="" xsi:schemaLocation="dian:gov:co:facturaelectronica:NominaIndividual NominaIndividualElectronicaXSD.xsd"><ext:UBLExtensions><ext:UBLExtension><ext:ExtensionContent><ds:Signature Id="xmlsig-135b3cc1-1d1c-4ddd-a4c0-704a880a352b"> | ||||||
|  | <ds:SignedInfo> | ||||||
|  | <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> | ||||||
|  | <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> | ||||||
|  | <ds:Reference Id="xmldsig-135b3cc1-1d1c-4ddd-a4c0-704a880a352b-ref0" URI=""> | ||||||
|  | <ds:Transforms> | ||||||
|  | <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> | ||||||
|  | </ds:Transforms> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>mf3prH7SIB1Df0Z/nOPdRGG0DKXP8oCra41918zaCyg=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | <ds:Reference Id="xmldsig-135b3cc1-1d1c-4ddd-a4c0-704a880a352b-ref1" URI="#xmldsig-135b3cc1-1d1c-4ddd-a4c0-704a880a352b-KeyInfo"> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>H3dF/siCNdG6iSy15jUQct1k4qswXBZToWJH6tsptpk=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | <ds:Reference URI="#xmldsig-135b3cc1-1d1c-4ddd-a4c0-704a880a352b-signedprops" Type="http://uri.etsi.org/01903#SignedProperties"> | ||||||
|  | <ds:Transforms> | ||||||
|  | <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> | ||||||
|  | </ds:Transforms> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>IqiqJKHTI0OAWva1xZ+ZOk9ooGkzEa4hReQCr4/W778=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | </ds:SignedInfo> | ||||||
|  | <ds:SignatureValue>Nv0nFvZ4Y3KIaPODEiOFgThDYb+DNKlJrRUAOrIxcNvtotpK7Y91JnYbUgFvl28b | ||||||
|  | Z5V/catUMyOclGDjPzslTBcHXExleb5eIgUB8URdNvdrB78iXFUOfPc+ESFomru8 | ||||||
|  | jyPX9cZw24ZYBmQqqusvqIkf/tIARFGZ+7AzXkp28dBRFyWtgjESn60DIrFjm9x5 | ||||||
|  | Pthv1K95gytjrrpwvdk77KN4uumlCbGoc2Pizbj+ufijbnxEPDS7fS7RR0Qv9uz/ | ||||||
|  | 2X7znR10TK8+gwMz7AVRYQi90ZbhOadxf3j+HVAlHtw+JHbrPSC+7xBOiPPStY6o | ||||||
|  | 6TkQU+ZMpz2IUovjqREXow==</ds:SignatureValue> | ||||||
|  | <ds:KeyInfo Id="xmldsig-135b3cc1-1d1c-4ddd-a4c0-704a880a352b-KeyInfo"> | ||||||
|  | <ds:X509Data> | ||||||
|  | <ds:X509Certificate>MIIH8TCCBdmgAwIBAgIIQxaPJd4YTlMwDQYJKoZIhvcNAQELBQAwgbYxIzAhBgkq | ||||||
|  | hkiG9w0BCQEWFGluZm9AYW5kZXNzY2QuY29tLmNvMSYwJAYDVQQDEx1DQSBBTkRF | ||||||
|  | UyBTQ0QgUy5BLiBDbGFzZSBJSSB2MzEwMC4GA1UECxMnRGl2aXNpb24gZGUgY2Vy | ||||||
|  | dGlmaWNhY2lvbiBlbnRpZGFkIGZpbmFsMRIwEAYDVQQKEwlBbmRlcyBTQ0QxFDAS | ||||||
|  | BgNVBAcTC0JvZ290YSBELkMuMQswCQYDVQQGEwJDTzAeFw0yNDA1MTYwNTAwMDBa | ||||||
|  | Fw0yNTA1MTYwNDU5MDBaMIIBQDEtMCsGA1UECRMkVFYgNDYgQyA0MiBFU1RFIDc4 | ||||||
|  | OSBDT1JSIFNBTlRBIEVMRU5BMSIwIAYJKoZIhvcNAQkBFhNiaWNpcGl6emFAZ21h | ||||||
|  | aWwuY29tMRowGAYDVQQDExFCSUNJIFBJWlpBIFMuQS5TLjETMBEGA1UEBRMKOTAx | ||||||
|  | NTc1NTI4MjE2MDQGA1UEDBMtRW1pc29yIEZhY3R1cmEgRWxlY3Ryb25pY2EgLSBQ | ||||||
|  | ZXJzb25hIEp1cmlkaWNhMTswOQYDVQQLEzJFbWl0aWRvIHBvciBBbmRlcyBTQ0Qg | ||||||
|  | QWMgMjYgNjkgQyAwMyBUb3JyZSBCIE9mIDcwMTEQMA4GA1UEChMHR0VSRU5URTES | ||||||
|  | MBAGA1UEBwwJTUVERUxMw41OMRIwEAYDVQQIEwlBTlRJT1FVSUExCzAJBgNVBAYT | ||||||
|  | AkNPMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5J1O+4ZedrSBUsb+ | ||||||
|  | 9tjNPHI9RGeIJcJl3Wc/208OqMYcCwGLUkrYBgH78E7IayD5/wra04OU57cS1/+/ | ||||||
|  | yBUWYR60oqkaH2/8OXkJMqmjisVM/b58m7zyMw4TAF8N/PbswnrKukFU2acxISwT | ||||||
|  | Lu36HC4hshWw8bEGP54szvv1xnwqcOAWNBCxcBuc9k1JD+SIiqqPwHKh+6EDIoou | ||||||
|  | jo0H15w3rAxkHQRvYe6/IrpvH2sqJl1I3dLv0iqy9+d2l891KBA9Yebdw7m/+ufu | ||||||
|  | +eqs+0zKrwV6QLhRFmceHzEkPMTFepc2COGf80OUNbI6WWnspvDK97D8YG0MeifP | ||||||
|  | YveIPwIDAQABo4ICdDCCAnAwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBRA/iZp | ||||||
|  | RzInMtGsIcgu7M+N1TVo6DBvBggrBgEFBQcBAQRjMGEwNgYIKwYBBQUHMAKGKmh0 | ||||||
|  | dHA6Ly9jZXJ0cy5hbmRlc3NjZC5jb20uY28vQ2xhc2VJSXYzLmNydDAnBggrBgEF | ||||||
|  | BQcwAYYbaHR0cDovL29jc3AuYW5kZXNzY2QuY29tLmNvMB4GA1UdEQQXMBWBE2Jp | ||||||
|  | Y2lwaXp6YUBnbWFpbC5jb20wggEjBgNVHSAEggEaMIIBFjCBwQYNKwYBBAGB9EgB | ||||||
|  | AgYIADCBrzCBrAYIKwYBBQUHAgIwgZ8MgZxMYSB1dGlsaXphY2nDs24gZGUgZXN0 | ||||||
|  | ZSBjZXJ0aWZpY2FkbyBlc3TDoSBzdWpldGEgYSBsYSBQQyBkZSBGYWN0dXJhY2nD | ||||||
|  | s24gRWxlY3Ryw7NuaWNhIHkgRFBDIGVzdGFibGVjaWRhcyBwb3IgQW5kZXMgU0NE | ||||||
|  | LiBDw7NkaWdvIGRlIEFjcmVkaXRhY2nDs246IDE2LUVDRC0wMDQwUAYNKwYBBAGB | ||||||
|  | 9EgBAQEKADA/MD0GCCsGAQUFBwIBFjFodHRwczovL3d3dy5hbmRlc3NjZC5jb20u | ||||||
|  | Y28vZG9jcy9EUENfQW5kZXNTQ0QucGRmMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr | ||||||
|  | BgEFBQcDBDA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLmFuZGVzc2NkLmNv | ||||||
|  | bS5jby9DbGFzZUlJdjMuY3JsMB0GA1UdDgQWBBRKPoh3BJM7SxEL0UXkSne2MyFO | ||||||
|  | jjAOBgNVHQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQELBQADggIBAA6Zzor3kpJ6vNKv | ||||||
|  | TAeHaMfmJ/PaghQ1+Lab7Pwk+lsPsMETFu/IpEK5qij2bV54UNnqyLYOZtIbnWTG | ||||||
|  | qgT7QxQvy+/of/I3zzF+kH4/Lp2TSlHaDEb/airCZ3I2G23M9iaZzSwYuOsOaGwp | ||||||
|  | 4ovkXlYwQ7FVNfIIoAq95m9cBAigb06bRIlVBVTQq44hQFQQG6aSIT7SSPtCwPhB | ||||||
|  | 5CJzG09pmgbxizqN/yxdjWdfW6Av79dh6K4uQT++Vtyp5DuAkmfn0ehayrUbDLkH | ||||||
|  | 9jQFF128U5pnOPfKWf22acXqQBapesUSV/HZUZ3PXoWeHWXcMdz0azxOEunS4+px | ||||||
|  | fs5UzInRAmEcYwJHqJT3irFz+J2RsZ0WnJHrTGqFoXniQQH8QbCHehDTGN7/v/v1 | ||||||
|  | LQBr5PQBnSEWhmrQ9uFrwPyMMg3yd+L75TaHLZ0MTSVezAG52oM9jBiU5tYXkSio | ||||||
|  | EfPdIsGlG74BybULGSG2OlTINlblj/lj7pL67V+gY9EGN1zzNKL5sW4YXlXewa6K | ||||||
|  | dTpLmmzWzI8Cm+tOuuJDSHSwMjn525O+Z/oyKLjdQdyfg1KnZYwNZFpMmCwfP5nd | ||||||
|  | cm4F7Anzb9HX9ciluAxc6as9TsNoDDTSAGPuUr0QvXqXd9ZCgXdNzdFeiaYknLP5 | ||||||
|  | hT4f5CoO2M8qcG+CH7HnkaOHrSuK</ds:X509Certificate> | ||||||
|  | </ds:X509Data> | ||||||
|  | <ds:KeyValue> | ||||||
|  | <ds:RSAKeyValue> | ||||||
|  | <ds:Modulus>5J1O+4ZedrSBUsb+9tjNPHI9RGeIJcJl3Wc/208OqMYcCwGLUkrYBgH78E7IayD5 | ||||||
|  | /wra04OU57cS1/+/yBUWYR60oqkaH2/8OXkJMqmjisVM/b58m7zyMw4TAF8N/Pbs | ||||||
|  | wnrKukFU2acxISwTLu36HC4hshWw8bEGP54szvv1xnwqcOAWNBCxcBuc9k1JD+SI | ||||||
|  | iqqPwHKh+6EDIooujo0H15w3rAxkHQRvYe6/IrpvH2sqJl1I3dLv0iqy9+d2l891 | ||||||
|  | KBA9Yebdw7m/+ufu+eqs+0zKrwV6QLhRFmceHzEkPMTFepc2COGf80OUNbI6WWns | ||||||
|  | pvDK97D8YG0MeifPYveIPw==</ds:Modulus> | ||||||
|  | <ds:Exponent>AQAB</ds:Exponent> | ||||||
|  | </ds:RSAKeyValue> | ||||||
|  | </ds:KeyValue> | ||||||
|  | </ds:KeyInfo> | ||||||
|  | <ds:Object><xades:QualifyingProperties Target="#xmlsig-135b3cc1-1d1c-4ddd-a4c0-704a880a352b" Id="XadesObjects"><xades:SignedProperties Id="xmldsig-135b3cc1-1d1c-4ddd-a4c0-704a880a352b-signedprops"><xades:SignedSignatureProperties><xades:SigningTime>2025-03-16T16:51:23.354553</xades:SigningTime><xades:SigningCertificate><xades:Cert><xades:CertDigest><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>YcIPspAVFcNg+B/galYrdCLYvLIEwFI4KWdSzcuupPY=</ds:DigestValue></xades:CertDigest><xades:IssuerSerial><ds:X509IssuerName>C=CO, L=Bogota D.C., O=Andes SCD, OU=Division de certificacion entidad final, CN=CA ANDES SCD S.A. Clase II v3, OID.1.2.840.113549.1.9.1=info@andesscd.com.co</ds:X509IssuerName><ds:X509SerialNumber>4834208642831502931</ds:X509SerialNumber></xades:IssuerSerial></xades:Cert></xades:SigningCertificate><xades:SignaturePolicyIdentifier><xades:SignaturePolicyId><xades:SigPolicyId><xades:Identifier>https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf</xades:Identifier><xades:Description>Política de firma para facturas electrónicas de la República de Colombia.</xades:Description></xades:SigPolicyId><xades:SigPolicyHash><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>dMoMvtcG5aIzgYo0tIsSQeVJBDnUnfSOfBpxXrmor0Y=</ds:DigestValue></xades:SigPolicyHash></xades:SignaturePolicyId></xades:SignaturePolicyIdentifier><xades:SignerRole><xades:ClaimedRoles><xades:ClaimedRole>supplier</xades:ClaimedRole></xades:ClaimedRoles></xades:SignerRole></xades:SignedSignatureProperties></xades:SignedProperties></xades:QualifyingProperties></ds:Object></ds:Signature></ext:ExtensionContent></ext:UBLExtension></ext:UBLExtensions><Novedad CUNENov="false">false</Novedad><Periodo FechaIngreso="2022-01-05" FechaLiquidacionInicio="2024-04-01" FechaLiquidacionFin="2024-04-30" TiempoLaborado="1" FechaGen="2024-04-30"/><NumeroSecuenciaXML Prefijo="N" Consecutivo="000003" Numero="N000003"/><LugarGeneracionXML Pais="CO" DepartamentoEstado="05" MunicipioCiudad="05001" Idioma="es"/><ProveedorXML NIT="901575528" DV="2" SoftwareID="100b0d10-0ca0-4ad4-a894-b704a568cbf3" RazonSocial="BICI PIZZA S.A.S" SoftwareSC="23bd3a3e925c4cdf6c4b99c1eda9e64846526241a263b86f3ffc9673d91020625812ef6abdcf93b4c326b7b65999d6c1"/><CodigoQR>https://catalogo-vpfe-hab.dian.gov.co/document/searchqr?documentkey=beae68d136b80593b01b5cd7594bc86cc2f6ffd17d0238e5842e29ef6dfde62d26cb959764b6bf0943e73149596bfec0</CodigoQR><InformacionGeneral Version="V1.0: Documento Soporte de Pago de Nómina Electrónica" Ambiente="2" TipoXML="102" EncripCUNE="CUNE-SHA384" FechaGen="2024-04-30" HoraGen="08:01:00-05:00" PeriodoNomina="1" TipoMoneda="COP" TRM="0" CUNE="beae68d136b80593b01b5cd7594bc86cc2f6ffd17d0238e5842e29ef6dfde62d26cb959764b6bf0943e73149596bfec0"/><Empleador NIT="901575528" DV="2" Pais="CO" DepartamentoEstado="05" MunicipioCiudad="05001" Direccion="calle etrivial" RazonSocial="BICI PIZZA S.A.S"/><Trabajador TipoTrabajador="01" SubTipoTrabajador="00" AltoRiesgoPension="false" TipoDocumento="11" NumeroDocumento="901575528" PrimerApellido="GONZALEZ" SegundoApellido="" PrimerNombre="JUAN" LugarTrabajoPais="CO" LugarTrabajoDepartamentoEstado="05" LugarTrabajoMunicipioCiudad="05001" LugarTrabajoDireccion="CL 35C 102-17 BL 7 AP 101" SalarioIntegral="false" TipoContrato="1" Sueldo="2400000.0"/><Pago Forma="1" Metodo="10"/><FechasPagos><FechaPago>2024-04-30</FechaPago></FechasPagos><Devengados><Basico DiasTrabajados="30" SueldoTrabajado="2400000.00"/></Devengados><Deducciones><Salud Porcentaje="4.00" Deduccion="96000.0"/><FondoPension Porcentaje="4.00" Deduccion="96000.0"/></Deducciones><Redondeo>0</Redondeo><DevengadosTotal>2400000.00</DevengadosTotal><DeduccionesTotal>192000.00</DeduccionesTotal><ComprobanteTotal>2208000.00</ComprobanteTotal></NominaIndividual> | ||||||
							
								
								
									
										
											BIN
										
									
								
								examples/habilitacion/N000003.zip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								examples/habilitacion/N000003.zip
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										123
									
								
								examples/habilitacion/N000004.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								examples/habilitacion/N000004.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  |  | ||||||
|  | from facho import fe | ||||||
|  |  | ||||||
|  | SOFTWARE_PIN='20234' | ||||||
|  | SOFTWARE_ID='100b0d10-0ca0-4ad4-a894-b704a568cbf3' | ||||||
|  | NIT='901575528' | ||||||
|  | DV='2' | ||||||
|  |  | ||||||
|  | def extensions(nomina): | ||||||
|  |     return [] | ||||||
|  |  | ||||||
|  | def nomina(): | ||||||
|  |     nomina = fe.nomina.DIANNominaIndividual() | ||||||
|  |  | ||||||
|  |     nomina.asignar_fecha_pago('2024-04-30') | ||||||
|  |  | ||||||
|  |     nomina.asignar_metadata(fe.nomina.Metadata( | ||||||
|  |     novedad=fe.nomina.Novedad(value='false'), | ||||||
|  |         secuencia=fe.nomina.NumeroSecuencia( | ||||||
|  |             prefijo='N', | ||||||
|  |             consecutivo='000004' | ||||||
|  |         ), | ||||||
|  |         lugar_generacion=fe.nomina.Lugar( | ||||||
|  |             pais = fe.nomina.Pais( | ||||||
|  |                 code = 'CO' | ||||||
|  |             ), | ||||||
|  |             departamento = fe.nomina.Departamento( | ||||||
|  |                 code = '05' | ||||||
|  |             ), | ||||||
|  |             municipio = fe.nomina.Municipio( | ||||||
|  |                 code = '05001' | ||||||
|  |             ), | ||||||
|  |         ), | ||||||
|  |         proveedor=fe.nomina.Proveedor( | ||||||
|  | 	    razon_social='BICI PIZZA S.A.S', | ||||||
|  |             nit=NIT, | ||||||
|  |             dv=DV, | ||||||
|  |             software_id=SOFTWARE_ID, | ||||||
|  |             software_pin=SOFTWARE_PIN | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_periodo(fe.nomina.Periodo( | ||||||
|  |         fecha_ingreso= '2022-09-05', | ||||||
|  |         fecha_liquidacion_inicio='2024-04-01', | ||||||
|  |         fecha_liquidacion_fin='2024-04-30', | ||||||
|  |         fecha_generacion='2024-04-30' | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_informacion_general(fe.nomina.InformacionGeneral( | ||||||
|  |         fecha_generacion = '2024-04-30', | ||||||
|  |         hora_generacion = '08:01:00-05:00', | ||||||
|  |         tipo_ambiente = fe.nomina.InformacionGeneral.AMBIENTE_PRUEBAS, | ||||||
|  |         software_pin = SOFTWARE_PIN, | ||||||
|  |         periodo_nomina = fe.nomina.PeriodoNomina(code='1'), | ||||||
|  |         tipo_moneda = fe.nomina.TipoMoneda(code='COP') | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_pago(fe.nomina.Pago( | ||||||
|  |         forma=fe.nomina.FormaPago( | ||||||
|  |             code='1', | ||||||
|  |         ), | ||||||
|  |         metodo=fe.nomina.MetodoPago( | ||||||
|  |             code='10' | ||||||
|  |         ) | ||||||
|  |     )) | ||||||
|  |     nomina.asignar_empleador(fe.nomina.Empleador( | ||||||
|  | 	razon_social='BICI PIZZA S.A.S', | ||||||
|  |         nit = NIT, | ||||||
|  |         dv = DV, | ||||||
|  |         pais = fe.nomina.Pais( | ||||||
|  |             code = 'CO' | ||||||
|  |         ), | ||||||
|  |         departamento = fe.nomina.Departamento( | ||||||
|  |             code = '05' | ||||||
|  |         ), | ||||||
|  |         municipio = fe.nomina.Municipio( | ||||||
|  |             code = '05001' | ||||||
|  |         ), | ||||||
|  |         direccion = 'calle etrivial' | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.asignar_trabajador(fe.nomina.Trabajador( | ||||||
|  |         tipo_contrato = fe.nomina.TipoContrato( | ||||||
|  |             code = '1' | ||||||
|  |         ), | ||||||
|  |         alto_riesgo = False, | ||||||
|  |         tipo_documento = fe.nomina.TipoDocumento( | ||||||
|  |             code = '11' | ||||||
|  |         ), | ||||||
|  |         primer_apellido = 'GIRALDO', | ||||||
|  |         segundo_apellido = '', | ||||||
|  |         primer_nombre = 'VIVIANA', | ||||||
|  |         lugar_trabajo = fe.nomina.LugarTrabajo( | ||||||
|  |             pais = fe.nomina.Pais(code='CO'), | ||||||
|  |             departamento = fe.nomina.Departamento(code='05'), | ||||||
|  |             municipio = fe.nomina.Municipio(code='05001'), | ||||||
|  |             direccion = 'CL 35C 102-17 BL 7 AP 101' | ||||||
|  |         ), | ||||||
|  |         numero_documento = NIT, | ||||||
|  |         tipo = fe.nomina.TipoTrabajador( | ||||||
|  |             code = '01' | ||||||
|  |         ), | ||||||
|  |         salario_integral = False, | ||||||
|  |         sueldo = fe.nomina.Amount(1160000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_devengado(fe.nomina.DevengadoBasico( | ||||||
|  |         dias_trabajados = 30, | ||||||
|  |         sueldo_trabajado = fe.nomina.Amount(1160000) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_deduccion(fe.nomina.DeduccionSalud( | ||||||
|  |         porcentaje = fe.nomina.Amount(4), | ||||||
|  |         deduccion = fe.nomina.Amount(46400) | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     nomina.adicionar_deduccion(fe.nomina.DeduccionFondoPension( | ||||||
|  |         porcentaje=fe.nomina.Amount(4), | ||||||
|  |         deduccion = fe.nomina.Amount(46400) | ||||||
|  |     )) | ||||||
|  |     return nomina | ||||||
|  |      | ||||||
							
								
								
									
										89
									
								
								examples/habilitacion/N000004.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								examples/habilitacion/N000004.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | <?xml version='1.0' encoding='UTF-8'?> | ||||||
|  | <NominaIndividual xmlns:atd="urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2" xmlns="dian:gov:co:facturaelectronica:NominaIndividual" xmlns:fe="http://www.dian.gov.co/contratos/facturaelectronica/v1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cdt="urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1" xmlns:clm54217="urn:un:unece:uncefact:codelist:specification:54217:2001" xmlns:clmIANAMIMEMediaType="urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:sts="dian:gov:co:facturaelectronica:Structures-2-1" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:sig="http://www.w3.org/2000/09/xmldsig#" SchemaLocation="" xsi:schemaLocation="dian:gov:co:facturaelectronica:NominaIndividual NominaIndividualElectronicaXSD.xsd"><ext:UBLExtensions><ext:UBLExtension><ext:ExtensionContent><ds:Signature Id="xmlsig-bf43fedd-6780-438f-afe3-ac062d8b8072"> | ||||||
|  | <ds:SignedInfo> | ||||||
|  | <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> | ||||||
|  | <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> | ||||||
|  | <ds:Reference Id="xmldsig-bf43fedd-6780-438f-afe3-ac062d8b8072-ref0" URI=""> | ||||||
|  | <ds:Transforms> | ||||||
|  | <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> | ||||||
|  | </ds:Transforms> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>ZAE71pLQXXnN5+540pnkxH5ALNBQcecMdLWFKTKby0g=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | <ds:Reference Id="xmldsig-bf43fedd-6780-438f-afe3-ac062d8b8072-ref1" URI="#xmldsig-bf43fedd-6780-438f-afe3-ac062d8b8072-KeyInfo"> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>kNyh65TH4KfF6wqRoy1duEawgkvOlr2rYLCNfdTfK1c=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | <ds:Reference URI="#xmldsig-bf43fedd-6780-438f-afe3-ac062d8b8072-signedprops" Type="http://uri.etsi.org/01903#SignedProperties"> | ||||||
|  | <ds:Transforms> | ||||||
|  | <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> | ||||||
|  | </ds:Transforms> | ||||||
|  | <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> | ||||||
|  | <ds:DigestValue>BoPBi5C0tXfV04cf74M4jktBxf9eVsXk5IWqGdeOSHw=</ds:DigestValue> | ||||||
|  | </ds:Reference> | ||||||
|  | </ds:SignedInfo> | ||||||
|  | <ds:SignatureValue>pw5WDlbd4GhnSAJKlTEDjsb1+VAVtyyXWA/isvGz4LHY5n1Fm4hiN7fD3JIrfOBj | ||||||
|  | z/tUfROLzbbywUnVklfaDri6txZlFFwa9SY8MO38bgE0HUxGq5khb/4uzktGRInp | ||||||
|  | H3i0TG5i42YB83PQItSLiEgPWqGVolj5sWfUqD81Ck4CvgtKuZgnn9JPLgP0sjjT | ||||||
|  | BUjKcMt4K+ZLvXumehKKCzEbtoaa5DHKUrpuCU2giGMMPElwaTulFA5kNLBnAk2n | ||||||
|  | HBCiIq+YZ2C3BqE+WQptcQDIObmEnRURvvUTB64gCh4Tigmq6vnv/dMPWmQvohmp | ||||||
|  | ETIZDwU0/xdGcUK7Ujyl4g==</ds:SignatureValue> | ||||||
|  | <ds:KeyInfo Id="xmldsig-bf43fedd-6780-438f-afe3-ac062d8b8072-KeyInfo"> | ||||||
|  | <ds:X509Data> | ||||||
|  | <ds:X509Certificate>MIIH8TCCBdmgAwIBAgIIQxaPJd4YTlMwDQYJKoZIhvcNAQELBQAwgbYxIzAhBgkq | ||||||
|  | hkiG9w0BCQEWFGluZm9AYW5kZXNzY2QuY29tLmNvMSYwJAYDVQQDEx1DQSBBTkRF | ||||||
|  | UyBTQ0QgUy5BLiBDbGFzZSBJSSB2MzEwMC4GA1UECxMnRGl2aXNpb24gZGUgY2Vy | ||||||
|  | dGlmaWNhY2lvbiBlbnRpZGFkIGZpbmFsMRIwEAYDVQQKEwlBbmRlcyBTQ0QxFDAS | ||||||
|  | BgNVBAcTC0JvZ290YSBELkMuMQswCQYDVQQGEwJDTzAeFw0yNDA1MTYwNTAwMDBa | ||||||
|  | Fw0yNTA1MTYwNDU5MDBaMIIBQDEtMCsGA1UECRMkVFYgNDYgQyA0MiBFU1RFIDc4 | ||||||
|  | OSBDT1JSIFNBTlRBIEVMRU5BMSIwIAYJKoZIhvcNAQkBFhNiaWNpcGl6emFAZ21h | ||||||
|  | aWwuY29tMRowGAYDVQQDExFCSUNJIFBJWlpBIFMuQS5TLjETMBEGA1UEBRMKOTAx | ||||||
|  | NTc1NTI4MjE2MDQGA1UEDBMtRW1pc29yIEZhY3R1cmEgRWxlY3Ryb25pY2EgLSBQ | ||||||
|  | ZXJzb25hIEp1cmlkaWNhMTswOQYDVQQLEzJFbWl0aWRvIHBvciBBbmRlcyBTQ0Qg | ||||||
|  | QWMgMjYgNjkgQyAwMyBUb3JyZSBCIE9mIDcwMTEQMA4GA1UEChMHR0VSRU5URTES | ||||||
|  | MBAGA1UEBwwJTUVERUxMw41OMRIwEAYDVQQIEwlBTlRJT1FVSUExCzAJBgNVBAYT | ||||||
|  | AkNPMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5J1O+4ZedrSBUsb+ | ||||||
|  | 9tjNPHI9RGeIJcJl3Wc/208OqMYcCwGLUkrYBgH78E7IayD5/wra04OU57cS1/+/ | ||||||
|  | yBUWYR60oqkaH2/8OXkJMqmjisVM/b58m7zyMw4TAF8N/PbswnrKukFU2acxISwT | ||||||
|  | Lu36HC4hshWw8bEGP54szvv1xnwqcOAWNBCxcBuc9k1JD+SIiqqPwHKh+6EDIoou | ||||||
|  | jo0H15w3rAxkHQRvYe6/IrpvH2sqJl1I3dLv0iqy9+d2l891KBA9Yebdw7m/+ufu | ||||||
|  | +eqs+0zKrwV6QLhRFmceHzEkPMTFepc2COGf80OUNbI6WWnspvDK97D8YG0MeifP | ||||||
|  | YveIPwIDAQABo4ICdDCCAnAwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBRA/iZp | ||||||
|  | RzInMtGsIcgu7M+N1TVo6DBvBggrBgEFBQcBAQRjMGEwNgYIKwYBBQUHMAKGKmh0 | ||||||
|  | dHA6Ly9jZXJ0cy5hbmRlc3NjZC5jb20uY28vQ2xhc2VJSXYzLmNydDAnBggrBgEF | ||||||
|  | BQcwAYYbaHR0cDovL29jc3AuYW5kZXNzY2QuY29tLmNvMB4GA1UdEQQXMBWBE2Jp | ||||||
|  | Y2lwaXp6YUBnbWFpbC5jb20wggEjBgNVHSAEggEaMIIBFjCBwQYNKwYBBAGB9EgB | ||||||
|  | AgYIADCBrzCBrAYIKwYBBQUHAgIwgZ8MgZxMYSB1dGlsaXphY2nDs24gZGUgZXN0 | ||||||
|  | ZSBjZXJ0aWZpY2FkbyBlc3TDoSBzdWpldGEgYSBsYSBQQyBkZSBGYWN0dXJhY2nD | ||||||
|  | s24gRWxlY3Ryw7NuaWNhIHkgRFBDIGVzdGFibGVjaWRhcyBwb3IgQW5kZXMgU0NE | ||||||
|  | LiBDw7NkaWdvIGRlIEFjcmVkaXRhY2nDs246IDE2LUVDRC0wMDQwUAYNKwYBBAGB | ||||||
|  | 9EgBAQEKADA/MD0GCCsGAQUFBwIBFjFodHRwczovL3d3dy5hbmRlc3NjZC5jb20u | ||||||
|  | Y28vZG9jcy9EUENfQW5kZXNTQ0QucGRmMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr | ||||||
|  | BgEFBQcDBDA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLmFuZGVzc2NkLmNv | ||||||
|  | bS5jby9DbGFzZUlJdjMuY3JsMB0GA1UdDgQWBBRKPoh3BJM7SxEL0UXkSne2MyFO | ||||||
|  | jjAOBgNVHQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQELBQADggIBAA6Zzor3kpJ6vNKv | ||||||
|  | TAeHaMfmJ/PaghQ1+Lab7Pwk+lsPsMETFu/IpEK5qij2bV54UNnqyLYOZtIbnWTG | ||||||
|  | qgT7QxQvy+/of/I3zzF+kH4/Lp2TSlHaDEb/airCZ3I2G23M9iaZzSwYuOsOaGwp | ||||||
|  | 4ovkXlYwQ7FVNfIIoAq95m9cBAigb06bRIlVBVTQq44hQFQQG6aSIT7SSPtCwPhB | ||||||
|  | 5CJzG09pmgbxizqN/yxdjWdfW6Av79dh6K4uQT++Vtyp5DuAkmfn0ehayrUbDLkH | ||||||
|  | 9jQFF128U5pnOPfKWf22acXqQBapesUSV/HZUZ3PXoWeHWXcMdz0azxOEunS4+px | ||||||
|  | fs5UzInRAmEcYwJHqJT3irFz+J2RsZ0WnJHrTGqFoXniQQH8QbCHehDTGN7/v/v1 | ||||||
|  | LQBr5PQBnSEWhmrQ9uFrwPyMMg3yd+L75TaHLZ0MTSVezAG52oM9jBiU5tYXkSio | ||||||
|  | EfPdIsGlG74BybULGSG2OlTINlblj/lj7pL67V+gY9EGN1zzNKL5sW4YXlXewa6K | ||||||
|  | dTpLmmzWzI8Cm+tOuuJDSHSwMjn525O+Z/oyKLjdQdyfg1KnZYwNZFpMmCwfP5nd | ||||||
|  | cm4F7Anzb9HX9ciluAxc6as9TsNoDDTSAGPuUr0QvXqXd9ZCgXdNzdFeiaYknLP5 | ||||||
|  | hT4f5CoO2M8qcG+CH7HnkaOHrSuK</ds:X509Certificate> | ||||||
|  | </ds:X509Data> | ||||||
|  | <ds:KeyValue> | ||||||
|  | <ds:RSAKeyValue> | ||||||
|  | <ds:Modulus>5J1O+4ZedrSBUsb+9tjNPHI9RGeIJcJl3Wc/208OqMYcCwGLUkrYBgH78E7IayD5 | ||||||
|  | /wra04OU57cS1/+/yBUWYR60oqkaH2/8OXkJMqmjisVM/b58m7zyMw4TAF8N/Pbs | ||||||
|  | wnrKukFU2acxISwTLu36HC4hshWw8bEGP54szvv1xnwqcOAWNBCxcBuc9k1JD+SI | ||||||
|  | iqqPwHKh+6EDIooujo0H15w3rAxkHQRvYe6/IrpvH2sqJl1I3dLv0iqy9+d2l891 | ||||||
|  | KBA9Yebdw7m/+ufu+eqs+0zKrwV6QLhRFmceHzEkPMTFepc2COGf80OUNbI6WWns | ||||||
|  | pvDK97D8YG0MeifPYveIPw==</ds:Modulus> | ||||||
|  | <ds:Exponent>AQAB</ds:Exponent> | ||||||
|  | </ds:RSAKeyValue> | ||||||
|  | </ds:KeyValue> | ||||||
|  | </ds:KeyInfo> | ||||||
|  | <ds:Object><xades:QualifyingProperties Target="#xmlsig-bf43fedd-6780-438f-afe3-ac062d8b8072" Id="XadesObjects"><xades:SignedProperties Id="xmldsig-bf43fedd-6780-438f-afe3-ac062d8b8072-signedprops"><xades:SignedSignatureProperties><xades:SigningTime>2025-03-16T16:51:26.699846</xades:SigningTime><xades:SigningCertificate><xades:Cert><xades:CertDigest><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>YcIPspAVFcNg+B/galYrdCLYvLIEwFI4KWdSzcuupPY=</ds:DigestValue></xades:CertDigest><xades:IssuerSerial><ds:X509IssuerName>C=CO, L=Bogota D.C., O=Andes SCD, OU=Division de certificacion entidad final, CN=CA ANDES SCD S.A. Clase II v3, OID.1.2.840.113549.1.9.1=info@andesscd.com.co</ds:X509IssuerName><ds:X509SerialNumber>4834208642831502931</ds:X509SerialNumber></xades:IssuerSerial></xades:Cert></xades:SigningCertificate><xades:SignaturePolicyIdentifier><xades:SignaturePolicyId><xades:SigPolicyId><xades:Identifier>https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf</xades:Identifier><xades:Description>Política de firma para facturas electrónicas de la República de Colombia.</xades:Description></xades:SigPolicyId><xades:SigPolicyHash><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>dMoMvtcG5aIzgYo0tIsSQeVJBDnUnfSOfBpxXrmor0Y=</ds:DigestValue></xades:SigPolicyHash></xades:SignaturePolicyId></xades:SignaturePolicyIdentifier><xades:SignerRole><xades:ClaimedRoles><xades:ClaimedRole>supplier</xades:ClaimedRole></xades:ClaimedRoles></xades:SignerRole></xades:SignedSignatureProperties></xades:SignedProperties></xades:QualifyingProperties></ds:Object></ds:Signature></ext:ExtensionContent></ext:UBLExtension></ext:UBLExtensions><Novedad CUNENov="false">false</Novedad><Periodo FechaIngreso="2022-09-05" FechaLiquidacionInicio="2024-04-01" FechaLiquidacionFin="2024-04-30" TiempoLaborado="1" FechaGen="2024-04-30"/><NumeroSecuenciaXML Prefijo="N" Consecutivo="000004" Numero="N000004"/><LugarGeneracionXML Pais="CO" DepartamentoEstado="05" MunicipioCiudad="05001" Idioma="es"/><ProveedorXML NIT="901575528" DV="2" SoftwareID="100b0d10-0ca0-4ad4-a894-b704a568cbf3" RazonSocial="BICI PIZZA S.A.S" SoftwareSC="61d2d18fc61f70cff4f5c5c2a5e17e5c904bf42179a8118242e994b40c22ef203741568ee51d94b81a7fbde4ea6a79aa"/><CodigoQR>https://catalogo-vpfe-hab.dian.gov.co/document/searchqr?documentkey=40d20d7af2d7ee471909e62fcb4beef7de82494e6c8df4e8349ca33a1246dea601b4cc9035e18972e853ecd435799eaa</CodigoQR><InformacionGeneral Version="V1.0: Documento Soporte de Pago de Nómina Electrónica" Ambiente="2" TipoXML="102" EncripCUNE="CUNE-SHA384" FechaGen="2024-04-30" HoraGen="08:01:00-05:00" PeriodoNomina="1" TipoMoneda="COP" TRM="0" CUNE="40d20d7af2d7ee471909e62fcb4beef7de82494e6c8df4e8349ca33a1246dea601b4cc9035e18972e853ecd435799eaa"/><Empleador NIT="901575528" DV="2" Pais="CO" DepartamentoEstado="05" MunicipioCiudad="05001" Direccion="calle etrivial" RazonSocial="BICI PIZZA S.A.S"/><Trabajador TipoTrabajador="01" SubTipoTrabajador="00" AltoRiesgoPension="false" TipoDocumento="11" NumeroDocumento="901575528" PrimerApellido="GIRALDO" SegundoApellido="" PrimerNombre="VIVIANA" LugarTrabajoPais="CO" LugarTrabajoDepartamentoEstado="05" LugarTrabajoMunicipioCiudad="05001" LugarTrabajoDireccion="CL 35C 102-17 BL 7 AP 101" SalarioIntegral="false" TipoContrato="1" Sueldo="1160000.0"/><Pago Forma="1" Metodo="10"/><FechasPagos><FechaPago>2024-04-30</FechaPago></FechasPagos><Devengados><Basico DiasTrabajados="30" SueldoTrabajado="1160000.00"/></Devengados><Deducciones><Salud Porcentaje="4.00" Deduccion="46400.0"/><FondoPension Porcentaje="4.00" Deduccion="46400.0"/></Deducciones><Redondeo>0</Redondeo><DevengadosTotal>1160000.00</DevengadosTotal><DeduccionesTotal>92800.00</DeduccionesTotal><ComprobanteTotal>1067200.00</ComprobanteTotal></NominaIndividual> | ||||||
							
								
								
									
										
											BIN
										
									
								
								examples/habilitacion/N000004.zip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								examples/habilitacion/N000004.zip
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								experimental/facho-signer/AUTHORS
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								experimental/facho-signer/AUTHORS
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										674
									
								
								experimental/facho-signer/COPYING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										674
									
								
								experimental/facho-signer/COPYING
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,674 @@ | |||||||
|  |                     GNU GENERAL PUBLIC LICENSE | ||||||
|  |                        Version 3, 29 June 2007 | ||||||
|  |  | ||||||
|  |  Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> | ||||||
|  |  Everyone is permitted to copy and distribute verbatim copies | ||||||
|  |  of this license document, but changing it is not allowed. | ||||||
|  |  | ||||||
|  |                             Preamble | ||||||
|  |  | ||||||
|  |   The GNU General Public License is a free, copyleft license for | ||||||
|  | software and other kinds of works. | ||||||
|  |  | ||||||
|  |   The licenses for most software and other practical works are designed | ||||||
|  | to take away your freedom to share and change the works.  By contrast, | ||||||
|  | the GNU General Public License is intended to guarantee your freedom to | ||||||
|  | share and change all versions of a program--to make sure it remains free | ||||||
|  | software for all its users.  We, the Free Software Foundation, use the | ||||||
|  | GNU General Public License for most of our software; it applies also to | ||||||
|  | any other work released this way by its authors.  You can apply it to | ||||||
|  | your programs, too. | ||||||
|  |  | ||||||
|  |   When we speak of free software, we are referring to freedom, not | ||||||
|  | price.  Our General Public Licenses are designed to make sure that you | ||||||
|  | have the freedom to distribute copies of free software (and charge for | ||||||
|  | them if you wish), that you receive source code or can get it if you | ||||||
|  | want it, that you can change the software or use pieces of it in new | ||||||
|  | free programs, and that you know you can do these things. | ||||||
|  |  | ||||||
|  |   To protect your rights, we need to prevent others from denying you | ||||||
|  | these rights or asking you to surrender the rights.  Therefore, you have | ||||||
|  | certain responsibilities if you distribute copies of the software, or if | ||||||
|  | you modify it: responsibilities to respect the freedom of others. | ||||||
|  |  | ||||||
|  |   For example, if you distribute copies of such a program, whether | ||||||
|  | gratis or for a fee, you must pass on to the recipients the same | ||||||
|  | freedoms that you received.  You must make sure that they, too, receive | ||||||
|  | or can get the source code.  And you must show them these terms so they | ||||||
|  | know their rights. | ||||||
|  |  | ||||||
|  |   Developers that use the GNU GPL protect your rights with two steps: | ||||||
|  | (1) assert copyright on the software, and (2) offer you this License | ||||||
|  | giving you legal permission to copy, distribute and/or modify it. | ||||||
|  |  | ||||||
|  |   For the developers' and authors' protection, the GPL clearly explains | ||||||
|  | that there is no warranty for this free software.  For both users' and | ||||||
|  | authors' sake, the GPL requires that modified versions be marked as | ||||||
|  | changed, so that their problems will not be attributed erroneously to | ||||||
|  | authors of previous versions. | ||||||
|  |  | ||||||
|  |   Some devices are designed to deny users access to install or run | ||||||
|  | modified versions of the software inside them, although the manufacturer | ||||||
|  | can do so.  This is fundamentally incompatible with the aim of | ||||||
|  | protecting users' freedom to change the software.  The systematic | ||||||
|  | pattern of such abuse occurs in the area of products for individuals to | ||||||
|  | use, which is precisely where it is most unacceptable.  Therefore, we | ||||||
|  | have designed this version of the GPL to prohibit the practice for those | ||||||
|  | products.  If such problems arise substantially in other domains, we | ||||||
|  | stand ready to extend this provision to those domains in future versions | ||||||
|  | of the GPL, as needed to protect the freedom of users. | ||||||
|  |  | ||||||
|  |   Finally, every program is threatened constantly by software patents. | ||||||
|  | States should not allow patents to restrict development and use of | ||||||
|  | software on general-purpose computers, but in those that do, we wish to | ||||||
|  | avoid the special danger that patents applied to a free program could | ||||||
|  | make it effectively proprietary.  To prevent this, the GPL assures that | ||||||
|  | patents cannot be used to render the program non-free. | ||||||
|  |  | ||||||
|  |   The precise terms and conditions for copying, distribution and | ||||||
|  | modification follow. | ||||||
|  |  | ||||||
|  |                        TERMS AND CONDITIONS | ||||||
|  |  | ||||||
|  |   0. Definitions. | ||||||
|  |  | ||||||
|  |   "This License" refers to version 3 of the GNU General Public License. | ||||||
|  |  | ||||||
|  |   "Copyright" also means copyright-like laws that apply to other kinds of | ||||||
|  | works, such as semiconductor masks. | ||||||
|  |  | ||||||
|  |   "The Program" refers to any copyrightable work licensed under this | ||||||
|  | License.  Each licensee is addressed as "you".  "Licensees" and | ||||||
|  | "recipients" may be individuals or organizations. | ||||||
|  |  | ||||||
|  |   To "modify" a work means to copy from or adapt all or part of the work | ||||||
|  | in a fashion requiring copyright permission, other than the making of an | ||||||
|  | exact copy.  The resulting work is called a "modified version" of the | ||||||
|  | earlier work or a work "based on" the earlier work. | ||||||
|  |  | ||||||
|  |   A "covered work" means either the unmodified Program or a work based | ||||||
|  | on the Program. | ||||||
|  |  | ||||||
|  |   To "propagate" a work means to do anything with it that, without | ||||||
|  | permission, would make you directly or secondarily liable for | ||||||
|  | infringement under applicable copyright law, except executing it on a | ||||||
|  | computer or modifying a private copy.  Propagation includes copying, | ||||||
|  | distribution (with or without modification), making available to the | ||||||
|  | public, and in some countries other activities as well. | ||||||
|  |  | ||||||
|  |   To "convey" a work means any kind of propagation that enables other | ||||||
|  | parties to make or receive copies.  Mere interaction with a user through | ||||||
|  | a computer network, with no transfer of a copy, is not conveying. | ||||||
|  |  | ||||||
|  |   An interactive user interface displays "Appropriate Legal Notices" | ||||||
|  | to the extent that it includes a convenient and prominently visible | ||||||
|  | feature that (1) displays an appropriate copyright notice, and (2) | ||||||
|  | tells the user that there is no warranty for the work (except to the | ||||||
|  | extent that warranties are provided), that licensees may convey the | ||||||
|  | work under this License, and how to view a copy of this License.  If | ||||||
|  | the interface presents a list of user commands or options, such as a | ||||||
|  | menu, a prominent item in the list meets this criterion. | ||||||
|  |  | ||||||
|  |   1. Source Code. | ||||||
|  |  | ||||||
|  |   The "source code" for a work means the preferred form of the work | ||||||
|  | for making modifications to it.  "Object code" means any non-source | ||||||
|  | form of a work. | ||||||
|  |  | ||||||
|  |   A "Standard Interface" means an interface that either is an official | ||||||
|  | standard defined by a recognized standards body, or, in the case of | ||||||
|  | interfaces specified for a particular programming language, one that | ||||||
|  | is widely used among developers working in that language. | ||||||
|  |  | ||||||
|  |   The "System Libraries" of an executable work include anything, other | ||||||
|  | than the work as a whole, that (a) is included in the normal form of | ||||||
|  | packaging a Major Component, but which is not part of that Major | ||||||
|  | Component, and (b) serves only to enable use of the work with that | ||||||
|  | Major Component, or to implement a Standard Interface for which an | ||||||
|  | implementation is available to the public in source code form.  A | ||||||
|  | "Major Component", in this context, means a major essential component | ||||||
|  | (kernel, window system, and so on) of the specific operating system | ||||||
|  | (if any) on which the executable work runs, or a compiler used to | ||||||
|  | produce the work, or an object code interpreter used to run it. | ||||||
|  |  | ||||||
|  |   The "Corresponding Source" for a work in object code form means all | ||||||
|  | the source code needed to generate, install, and (for an executable | ||||||
|  | work) run the object code and to modify the work, including scripts to | ||||||
|  | control those activities.  However, it does not include the work's | ||||||
|  | System Libraries, or general-purpose tools or generally available free | ||||||
|  | programs which are used unmodified in performing those activities but | ||||||
|  | which are not part of the work.  For example, Corresponding Source | ||||||
|  | includes interface definition files associated with source files for | ||||||
|  | the work, and the source code for shared libraries and dynamically | ||||||
|  | linked subprograms that the work is specifically designed to require, | ||||||
|  | such as by intimate data communication or control flow between those | ||||||
|  | subprograms and other parts of the work. | ||||||
|  |  | ||||||
|  |   The Corresponding Source need not include anything that users | ||||||
|  | can regenerate automatically from other parts of the Corresponding | ||||||
|  | Source. | ||||||
|  |  | ||||||
|  |   The Corresponding Source for a work in source code form is that | ||||||
|  | same work. | ||||||
|  |  | ||||||
|  |   2. Basic Permissions. | ||||||
|  |  | ||||||
|  |   All rights granted under this License are granted for the term of | ||||||
|  | copyright on the Program, and are irrevocable provided the stated | ||||||
|  | conditions are met.  This License explicitly affirms your unlimited | ||||||
|  | permission to run the unmodified Program.  The output from running a | ||||||
|  | covered work is covered by this License only if the output, given its | ||||||
|  | content, constitutes a covered work.  This License acknowledges your | ||||||
|  | rights of fair use or other equivalent, as provided by copyright law. | ||||||
|  |  | ||||||
|  |   You may make, run and propagate covered works that you do not | ||||||
|  | convey, without conditions so long as your license otherwise remains | ||||||
|  | in force.  You may convey covered works to others for the sole purpose | ||||||
|  | of having them make modifications exclusively for you, or provide you | ||||||
|  | with facilities for running those works, provided that you comply with | ||||||
|  | the terms of this License in conveying all material for which you do | ||||||
|  | not control copyright.  Those thus making or running the covered works | ||||||
|  | for you must do so exclusively on your behalf, under your direction | ||||||
|  | and control, on terms that prohibit them from making any copies of | ||||||
|  | your copyrighted material outside their relationship with you. | ||||||
|  |  | ||||||
|  |   Conveying under any other circumstances is permitted solely under | ||||||
|  | the conditions stated below.  Sublicensing is not allowed; section 10 | ||||||
|  | makes it unnecessary. | ||||||
|  |  | ||||||
|  |   3. Protecting Users' Legal Rights From Anti-Circumvention Law. | ||||||
|  |  | ||||||
|  |   No covered work shall be deemed part of an effective technological | ||||||
|  | measure under any applicable law fulfilling obligations under article | ||||||
|  | 11 of the WIPO copyright treaty adopted on 20 December 1996, or | ||||||
|  | similar laws prohibiting or restricting circumvention of such | ||||||
|  | measures. | ||||||
|  |  | ||||||
|  |   When you convey a covered work, you waive any legal power to forbid | ||||||
|  | circumvention of technological measures to the extent such circumvention | ||||||
|  | is effected by exercising rights under this License with respect to | ||||||
|  | the covered work, and you disclaim any intention to limit operation or | ||||||
|  | modification of the work as a means of enforcing, against the work's | ||||||
|  | users, your or third parties' legal rights to forbid circumvention of | ||||||
|  | technological measures. | ||||||
|  |  | ||||||
|  |   4. Conveying Verbatim Copies. | ||||||
|  |  | ||||||
|  |   You may convey verbatim copies of the Program's source code as you | ||||||
|  | receive it, in any medium, provided that you conspicuously and | ||||||
|  | appropriately publish on each copy an appropriate copyright notice; | ||||||
|  | keep intact all notices stating that this License and any | ||||||
|  | non-permissive terms added in accord with section 7 apply to the code; | ||||||
|  | keep intact all notices of the absence of any warranty; and give all | ||||||
|  | recipients a copy of this License along with the Program. | ||||||
|  |  | ||||||
|  |   You may charge any price or no price for each copy that you convey, | ||||||
|  | and you may offer support or warranty protection for a fee. | ||||||
|  |  | ||||||
|  |   5. Conveying Modified Source Versions. | ||||||
|  |  | ||||||
|  |   You may convey a work based on the Program, or the modifications to | ||||||
|  | produce it from the Program, in the form of source code under the | ||||||
|  | terms of section 4, provided that you also meet all of these conditions: | ||||||
|  |  | ||||||
|  |     a) The work must carry prominent notices stating that you modified | ||||||
|  |     it, and giving a relevant date. | ||||||
|  |  | ||||||
|  |     b) The work must carry prominent notices stating that it is | ||||||
|  |     released under this License and any conditions added under section | ||||||
|  |     7.  This requirement modifies the requirement in section 4 to | ||||||
|  |     "keep intact all notices". | ||||||
|  |  | ||||||
|  |     c) You must license the entire work, as a whole, under this | ||||||
|  |     License to anyone who comes into possession of a copy.  This | ||||||
|  |     License will therefore apply, along with any applicable section 7 | ||||||
|  |     additional terms, to the whole of the work, and all its parts, | ||||||
|  |     regardless of how they are packaged.  This License gives no | ||||||
|  |     permission to license the work in any other way, but it does not | ||||||
|  |     invalidate such permission if you have separately received it. | ||||||
|  |  | ||||||
|  |     d) If the work has interactive user interfaces, each must display | ||||||
|  |     Appropriate Legal Notices; however, if the Program has interactive | ||||||
|  |     interfaces that do not display Appropriate Legal Notices, your | ||||||
|  |     work need not make them do so. | ||||||
|  |  | ||||||
|  |   A compilation of a covered work with other separate and independent | ||||||
|  | works, which are not by their nature extensions of the covered work, | ||||||
|  | and which are not combined with it such as to form a larger program, | ||||||
|  | in or on a volume of a storage or distribution medium, is called an | ||||||
|  | "aggregate" if the compilation and its resulting copyright are not | ||||||
|  | used to limit the access or legal rights of the compilation's users | ||||||
|  | beyond what the individual works permit.  Inclusion of a covered work | ||||||
|  | in an aggregate does not cause this License to apply to the other | ||||||
|  | parts of the aggregate. | ||||||
|  |  | ||||||
|  |   6. Conveying Non-Source Forms. | ||||||
|  |  | ||||||
|  |   You may convey a covered work in object code form under the terms | ||||||
|  | of sections 4 and 5, provided that you also convey the | ||||||
|  | machine-readable Corresponding Source under the terms of this License, | ||||||
|  | in one of these ways: | ||||||
|  |  | ||||||
|  |     a) Convey the object code in, or embodied in, a physical product | ||||||
|  |     (including a physical distribution medium), accompanied by the | ||||||
|  |     Corresponding Source fixed on a durable physical medium | ||||||
|  |     customarily used for software interchange. | ||||||
|  |  | ||||||
|  |     b) Convey the object code in, or embodied in, a physical product | ||||||
|  |     (including a physical distribution medium), accompanied by a | ||||||
|  |     written offer, valid for at least three years and valid for as | ||||||
|  |     long as you offer spare parts or customer support for that product | ||||||
|  |     model, to give anyone who possesses the object code either (1) a | ||||||
|  |     copy of the Corresponding Source for all the software in the | ||||||
|  |     product that is covered by this License, on a durable physical | ||||||
|  |     medium customarily used for software interchange, for a price no | ||||||
|  |     more than your reasonable cost of physically performing this | ||||||
|  |     conveying of source, or (2) access to copy the | ||||||
|  |     Corresponding Source from a network server at no charge. | ||||||
|  |  | ||||||
|  |     c) Convey individual copies of the object code with a copy of the | ||||||
|  |     written offer to provide the Corresponding Source.  This | ||||||
|  |     alternative is allowed only occasionally and noncommercially, and | ||||||
|  |     only if you received the object code with such an offer, in accord | ||||||
|  |     with subsection 6b. | ||||||
|  |  | ||||||
|  |     d) Convey the object code by offering access from a designated | ||||||
|  |     place (gratis or for a charge), and offer equivalent access to the | ||||||
|  |     Corresponding Source in the same way through the same place at no | ||||||
|  |     further charge.  You need not require recipients to copy the | ||||||
|  |     Corresponding Source along with the object code.  If the place to | ||||||
|  |     copy the object code is a network server, the Corresponding Source | ||||||
|  |     may be on a different server (operated by you or a third party) | ||||||
|  |     that supports equivalent copying facilities, provided you maintain | ||||||
|  |     clear directions next to the object code saying where to find the | ||||||
|  |     Corresponding Source.  Regardless of what server hosts the | ||||||
|  |     Corresponding Source, you remain obligated to ensure that it is | ||||||
|  |     available for as long as needed to satisfy these requirements. | ||||||
|  |  | ||||||
|  |     e) Convey the object code using peer-to-peer transmission, provided | ||||||
|  |     you inform other peers where the object code and Corresponding | ||||||
|  |     Source of the work are being offered to the general public at no | ||||||
|  |     charge under subsection 6d. | ||||||
|  |  | ||||||
|  |   A separable portion of the object code, whose source code is excluded | ||||||
|  | from the Corresponding Source as a System Library, need not be | ||||||
|  | included in conveying the object code work. | ||||||
|  |  | ||||||
|  |   A "User Product" is either (1) a "consumer product", which means any | ||||||
|  | tangible personal property which is normally used for personal, family, | ||||||
|  | or household purposes, or (2) anything designed or sold for incorporation | ||||||
|  | into a dwelling.  In determining whether a product is a consumer product, | ||||||
|  | doubtful cases shall be resolved in favor of coverage.  For a particular | ||||||
|  | product received by a particular user, "normally used" refers to a | ||||||
|  | typical or common use of that class of product, regardless of the status | ||||||
|  | of the particular user or of the way in which the particular user | ||||||
|  | actually uses, or expects or is expected to use, the product.  A product | ||||||
|  | is a consumer product regardless of whether the product has substantial | ||||||
|  | commercial, industrial or non-consumer uses, unless such uses represent | ||||||
|  | the only significant mode of use of the product. | ||||||
|  |  | ||||||
|  |   "Installation Information" for a User Product means any methods, | ||||||
|  | procedures, authorization keys, or other information required to install | ||||||
|  | and execute modified versions of a covered work in that User Product from | ||||||
|  | a modified version of its Corresponding Source.  The information must | ||||||
|  | suffice to ensure that the continued functioning of the modified object | ||||||
|  | code is in no case prevented or interfered with solely because | ||||||
|  | modification has been made. | ||||||
|  |  | ||||||
|  |   If you convey an object code work under this section in, or with, or | ||||||
|  | specifically for use in, a User Product, and the conveying occurs as | ||||||
|  | part of a transaction in which the right of possession and use of the | ||||||
|  | User Product is transferred to the recipient in perpetuity or for a | ||||||
|  | fixed term (regardless of how the transaction is characterized), the | ||||||
|  | Corresponding Source conveyed under this section must be accompanied | ||||||
|  | by the Installation Information.  But this requirement does not apply | ||||||
|  | if neither you nor any third party retains the ability to install | ||||||
|  | modified object code on the User Product (for example, the work has | ||||||
|  | been installed in ROM). | ||||||
|  |  | ||||||
|  |   The requirement to provide Installation Information does not include a | ||||||
|  | requirement to continue to provide support service, warranty, or updates | ||||||
|  | for a work that has been modified or installed by the recipient, or for | ||||||
|  | the User Product in which it has been modified or installed.  Access to a | ||||||
|  | network may be denied when the modification itself materially and | ||||||
|  | adversely affects the operation of the network or violates the rules and | ||||||
|  | protocols for communication across the network. | ||||||
|  |  | ||||||
|  |   Corresponding Source conveyed, and Installation Information provided, | ||||||
|  | in accord with this section must be in a format that is publicly | ||||||
|  | documented (and with an implementation available to the public in | ||||||
|  | source code form), and must require no special password or key for | ||||||
|  | unpacking, reading or copying. | ||||||
|  |  | ||||||
|  |   7. Additional Terms. | ||||||
|  |  | ||||||
|  |   "Additional permissions" are terms that supplement the terms of this | ||||||
|  | License by making exceptions from one or more of its conditions. | ||||||
|  | Additional permissions that are applicable to the entire Program shall | ||||||
|  | be treated as though they were included in this License, to the extent | ||||||
|  | that they are valid under applicable law.  If additional permissions | ||||||
|  | apply only to part of the Program, that part may be used separately | ||||||
|  | under those permissions, but the entire Program remains governed by | ||||||
|  | this License without regard to the additional permissions. | ||||||
|  |  | ||||||
|  |   When you convey a copy of a covered work, you may at your option | ||||||
|  | remove any additional permissions from that copy, or from any part of | ||||||
|  | it.  (Additional permissions may be written to require their own | ||||||
|  | removal in certain cases when you modify the work.)  You may place | ||||||
|  | additional permissions on material, added by you to a covered work, | ||||||
|  | for which you have or can give appropriate copyright permission. | ||||||
|  |  | ||||||
|  |   Notwithstanding any other provision of this License, for material you | ||||||
|  | add to a covered work, you may (if authorized by the copyright holders of | ||||||
|  | that material) supplement the terms of this License with terms: | ||||||
|  |  | ||||||
|  |     a) Disclaiming warranty or limiting liability differently from the | ||||||
|  |     terms of sections 15 and 16 of this License; or | ||||||
|  |  | ||||||
|  |     b) Requiring preservation of specified reasonable legal notices or | ||||||
|  |     author attributions in that material or in the Appropriate Legal | ||||||
|  |     Notices displayed by works containing it; or | ||||||
|  |  | ||||||
|  |     c) Prohibiting misrepresentation of the origin of that material, or | ||||||
|  |     requiring that modified versions of such material be marked in | ||||||
|  |     reasonable ways as different from the original version; or | ||||||
|  |  | ||||||
|  |     d) Limiting the use for publicity purposes of names of licensors or | ||||||
|  |     authors of the material; or | ||||||
|  |  | ||||||
|  |     e) Declining to grant rights under trademark law for use of some | ||||||
|  |     trade names, trademarks, or service marks; or | ||||||
|  |  | ||||||
|  |     f) Requiring indemnification of licensors and authors of that | ||||||
|  |     material by anyone who conveys the material (or modified versions of | ||||||
|  |     it) with contractual assumptions of liability to the recipient, for | ||||||
|  |     any liability that these contractual assumptions directly impose on | ||||||
|  |     those licensors and authors. | ||||||
|  |  | ||||||
|  |   All other non-permissive additional terms are considered "further | ||||||
|  | restrictions" within the meaning of section 10.  If the Program as you | ||||||
|  | received it, or any part of it, contains a notice stating that it is | ||||||
|  | governed by this License along with a term that is a further | ||||||
|  | restriction, you may remove that term.  If a license document contains | ||||||
|  | a further restriction but permits relicensing or conveying under this | ||||||
|  | License, you may add to a covered work material governed by the terms | ||||||
|  | of that license document, provided that the further restriction does | ||||||
|  | not survive such relicensing or conveying. | ||||||
|  |  | ||||||
|  |   If you add terms to a covered work in accord with this section, you | ||||||
|  | must place, in the relevant source files, a statement of the | ||||||
|  | additional terms that apply to those files, or a notice indicating | ||||||
|  | where to find the applicable terms. | ||||||
|  |  | ||||||
|  |   Additional terms, permissive or non-permissive, may be stated in the | ||||||
|  | form of a separately written license, or stated as exceptions; | ||||||
|  | the above requirements apply either way. | ||||||
|  |  | ||||||
|  |   8. Termination. | ||||||
|  |  | ||||||
|  |   You may not propagate or modify a covered work except as expressly | ||||||
|  | provided under this License.  Any attempt otherwise to propagate or | ||||||
|  | modify it is void, and will automatically terminate your rights under | ||||||
|  | this License (including any patent licenses granted under the third | ||||||
|  | paragraph of section 11). | ||||||
|  |  | ||||||
|  |   However, if you cease all violation of this License, then your | ||||||
|  | license from a particular copyright holder is reinstated (a) | ||||||
|  | provisionally, unless and until the copyright holder explicitly and | ||||||
|  | finally terminates your license, and (b) permanently, if the copyright | ||||||
|  | holder fails to notify you of the violation by some reasonable means | ||||||
|  | prior to 60 days after the cessation. | ||||||
|  |  | ||||||
|  |   Moreover, your license from a particular copyright holder is | ||||||
|  | reinstated permanently if the copyright holder notifies you of the | ||||||
|  | violation by some reasonable means, this is the first time you have | ||||||
|  | received notice of violation of this License (for any work) from that | ||||||
|  | copyright holder, and you cure the violation prior to 30 days after | ||||||
|  | your receipt of the notice. | ||||||
|  |  | ||||||
|  |   Termination of your rights under this section does not terminate the | ||||||
|  | licenses of parties who have received copies or rights from you under | ||||||
|  | this License.  If your rights have been terminated and not permanently | ||||||
|  | reinstated, you do not qualify to receive new licenses for the same | ||||||
|  | material under section 10. | ||||||
|  |  | ||||||
|  |   9. Acceptance Not Required for Having Copies. | ||||||
|  |  | ||||||
|  |   You are not required to accept this License in order to receive or | ||||||
|  | run a copy of the Program.  Ancillary propagation of a covered work | ||||||
|  | occurring solely as a consequence of using peer-to-peer transmission | ||||||
|  | to receive a copy likewise does not require acceptance.  However, | ||||||
|  | nothing other than this License grants you permission to propagate or | ||||||
|  | modify any covered work.  These actions infringe copyright if you do | ||||||
|  | not accept this License.  Therefore, by modifying or propagating a | ||||||
|  | covered work, you indicate your acceptance of this License to do so. | ||||||
|  |  | ||||||
|  |   10. Automatic Licensing of Downstream Recipients. | ||||||
|  |  | ||||||
|  |   Each time you convey a covered work, the recipient automatically | ||||||
|  | receives a license from the original licensors, to run, modify and | ||||||
|  | propagate that work, subject to this License.  You are not responsible | ||||||
|  | for enforcing compliance by third parties with this License. | ||||||
|  |  | ||||||
|  |   An "entity transaction" is a transaction transferring control of an | ||||||
|  | organization, or substantially all assets of one, or subdividing an | ||||||
|  | organization, or merging organizations.  If propagation of a covered | ||||||
|  | work results from an entity transaction, each party to that | ||||||
|  | transaction who receives a copy of the work also receives whatever | ||||||
|  | licenses to the work the party's predecessor in interest had or could | ||||||
|  | give under the previous paragraph, plus a right to possession of the | ||||||
|  | Corresponding Source of the work from the predecessor in interest, if | ||||||
|  | the predecessor has it or can get it with reasonable efforts. | ||||||
|  |  | ||||||
|  |   You may not impose any further restrictions on the exercise of the | ||||||
|  | rights granted or affirmed under this License.  For example, you may | ||||||
|  | not impose a license fee, royalty, or other charge for exercise of | ||||||
|  | rights granted under this License, and you may not initiate litigation | ||||||
|  | (including a cross-claim or counterclaim in a lawsuit) alleging that | ||||||
|  | any patent claim is infringed by making, using, selling, offering for | ||||||
|  | sale, or importing the Program or any portion of it. | ||||||
|  |  | ||||||
|  |   11. Patents. | ||||||
|  |  | ||||||
|  |   A "contributor" is a copyright holder who authorizes use under this | ||||||
|  | License of the Program or a work on which the Program is based.  The | ||||||
|  | work thus licensed is called the contributor's "contributor version". | ||||||
|  |  | ||||||
|  |   A contributor's "essential patent claims" are all patent claims | ||||||
|  | owned or controlled by the contributor, whether already acquired or | ||||||
|  | hereafter acquired, that would be infringed by some manner, permitted | ||||||
|  | by this License, of making, using, or selling its contributor version, | ||||||
|  | but do not include claims that would be infringed only as a | ||||||
|  | consequence of further modification of the contributor version.  For | ||||||
|  | purposes of this definition, "control" includes the right to grant | ||||||
|  | patent sublicenses in a manner consistent with the requirements of | ||||||
|  | this License. | ||||||
|  |  | ||||||
|  |   Each contributor grants you a non-exclusive, worldwide, royalty-free | ||||||
|  | patent license under the contributor's essential patent claims, to | ||||||
|  | make, use, sell, offer for sale, import and otherwise run, modify and | ||||||
|  | propagate the contents of its contributor version. | ||||||
|  |  | ||||||
|  |   In the following three paragraphs, a "patent license" is any express | ||||||
|  | agreement or commitment, however denominated, not to enforce a patent | ||||||
|  | (such as an express permission to practice a patent or covenant not to | ||||||
|  | sue for patent infringement).  To "grant" such a patent license to a | ||||||
|  | party means to make such an agreement or commitment not to enforce a | ||||||
|  | patent against the party. | ||||||
|  |  | ||||||
|  |   If you convey a covered work, knowingly relying on a patent license, | ||||||
|  | and the Corresponding Source of the work is not available for anyone | ||||||
|  | to copy, free of charge and under the terms of this License, through a | ||||||
|  | publicly available network server or other readily accessible means, | ||||||
|  | then you must either (1) cause the Corresponding Source to be so | ||||||
|  | available, or (2) arrange to deprive yourself of the benefit of the | ||||||
|  | patent license for this particular work, or (3) arrange, in a manner | ||||||
|  | consistent with the requirements of this License, to extend the patent | ||||||
|  | license to downstream recipients.  "Knowingly relying" means you have | ||||||
|  | actual knowledge that, but for the patent license, your conveying the | ||||||
|  | covered work in a country, or your recipient's use of the covered work | ||||||
|  | in a country, would infringe one or more identifiable patents in that | ||||||
|  | country that you have reason to believe are valid. | ||||||
|  |  | ||||||
|  |   If, pursuant to or in connection with a single transaction or | ||||||
|  | arrangement, you convey, or propagate by procuring conveyance of, a | ||||||
|  | covered work, and grant a patent license to some of the parties | ||||||
|  | receiving the covered work authorizing them to use, propagate, modify | ||||||
|  | or convey a specific copy of the covered work, then the patent license | ||||||
|  | you grant is automatically extended to all recipients of the covered | ||||||
|  | work and works based on it. | ||||||
|  |  | ||||||
|  |   A patent license is "discriminatory" if it does not include within | ||||||
|  | the scope of its coverage, prohibits the exercise of, or is | ||||||
|  | conditioned on the non-exercise of one or more of the rights that are | ||||||
|  | specifically granted under this License.  You may not convey a covered | ||||||
|  | work if you are a party to an arrangement with a third party that is | ||||||
|  | in the business of distributing software, under which you make payment | ||||||
|  | to the third party based on the extent of your activity of conveying | ||||||
|  | the work, and under which the third party grants, to any of the | ||||||
|  | parties who would receive the covered work from you, a discriminatory | ||||||
|  | patent license (a) in connection with copies of the covered work | ||||||
|  | conveyed by you (or copies made from those copies), or (b) primarily | ||||||
|  | for and in connection with specific products or compilations that | ||||||
|  | contain the covered work, unless you entered into that arrangement, | ||||||
|  | or that patent license was granted, prior to 28 March 2007. | ||||||
|  |  | ||||||
|  |   Nothing in this License shall be construed as excluding or limiting | ||||||
|  | any implied license or other defenses to infringement that may | ||||||
|  | otherwise be available to you under applicable patent law. | ||||||
|  |  | ||||||
|  |   12. No Surrender of Others' Freedom. | ||||||
|  |  | ||||||
|  |   If conditions are imposed on you (whether by court order, agreement or | ||||||
|  | otherwise) that contradict the conditions of this License, they do not | ||||||
|  | excuse you from the conditions of this License.  If you cannot convey a | ||||||
|  | covered work so as to satisfy simultaneously your obligations under this | ||||||
|  | License and any other pertinent obligations, then as a consequence you may | ||||||
|  | not convey it at all.  For example, if you agree to terms that obligate you | ||||||
|  | to collect a royalty for further conveying from those to whom you convey | ||||||
|  | the Program, the only way you could satisfy both those terms and this | ||||||
|  | License would be to refrain entirely from conveying the Program. | ||||||
|  |  | ||||||
|  |   13. Use with the GNU Affero General Public License. | ||||||
|  |  | ||||||
|  |   Notwithstanding any other provision of this License, you have | ||||||
|  | permission to link or combine any covered work with a work licensed | ||||||
|  | under version 3 of the GNU Affero General Public License into a single | ||||||
|  | combined work, and to convey the resulting work.  The terms of this | ||||||
|  | License will continue to apply to the part which is the covered work, | ||||||
|  | but the special requirements of the GNU Affero General Public License, | ||||||
|  | section 13, concerning interaction through a network will apply to the | ||||||
|  | combination as such. | ||||||
|  |  | ||||||
|  |   14. Revised Versions of this License. | ||||||
|  |  | ||||||
|  |   The Free Software Foundation may publish revised and/or new versions of | ||||||
|  | the GNU General Public License from time to time.  Such new versions will | ||||||
|  | be similar in spirit to the present version, but may differ in detail to | ||||||
|  | address new problems or concerns. | ||||||
|  |  | ||||||
|  |   Each version is given a distinguishing version number.  If the | ||||||
|  | Program specifies that a certain numbered version of the GNU General | ||||||
|  | Public License "or any later version" applies to it, you have the | ||||||
|  | option of following the terms and conditions either of that numbered | ||||||
|  | version or of any later version published by the Free Software | ||||||
|  | Foundation.  If the Program does not specify a version number of the | ||||||
|  | GNU General Public License, you may choose any version ever published | ||||||
|  | by the Free Software Foundation. | ||||||
|  |  | ||||||
|  |   If the Program specifies that a proxy can decide which future | ||||||
|  | versions of the GNU General Public License can be used, that proxy's | ||||||
|  | public statement of acceptance of a version permanently authorizes you | ||||||
|  | to choose that version for the Program. | ||||||
|  |  | ||||||
|  |   Later license versions may give you additional or different | ||||||
|  | permissions.  However, no additional obligations are imposed on any | ||||||
|  | author or copyright holder as a result of your choosing to follow a | ||||||
|  | later version. | ||||||
|  |  | ||||||
|  |   15. Disclaimer of Warranty. | ||||||
|  |  | ||||||
|  |   THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | ||||||
|  | APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | ||||||
|  | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | ||||||
|  | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | ||||||
|  | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||||
|  | PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | ||||||
|  | IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | ||||||
|  | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | ||||||
|  |  | ||||||
|  |   16. Limitation of Liability. | ||||||
|  |  | ||||||
|  |   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||||||
|  | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | ||||||
|  | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | ||||||
|  | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | ||||||
|  | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | ||||||
|  | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | ||||||
|  | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | ||||||
|  | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | ||||||
|  | SUCH DAMAGES. | ||||||
|  |  | ||||||
|  |   17. Interpretation of Sections 15 and 16. | ||||||
|  |  | ||||||
|  |   If the disclaimer of warranty and limitation of liability provided | ||||||
|  | above cannot be given local legal effect according to their terms, | ||||||
|  | reviewing courts shall apply local law that most closely approximates | ||||||
|  | an absolute waiver of all civil liability in connection with the | ||||||
|  | Program, unless a warranty or assumption of liability accompanies a | ||||||
|  | copy of the Program in return for a fee. | ||||||
|  |  | ||||||
|  |                      END OF TERMS AND CONDITIONS | ||||||
|  |  | ||||||
|  |             How to Apply These Terms to Your New Programs | ||||||
|  |  | ||||||
|  |   If you develop a new program, and you want it to be of the greatest | ||||||
|  | possible use to the public, the best way to achieve this is to make it | ||||||
|  | free software which everyone can redistribute and change under these terms. | ||||||
|  |  | ||||||
|  |   To do so, attach the following notices to the program.  It is safest | ||||||
|  | to attach them to the start of each source file to most effectively | ||||||
|  | state the exclusion of warranty; and each file should have at least | ||||||
|  | the "copyright" line and a pointer to where the full notice is found. | ||||||
|  |  | ||||||
|  |     <one line to give the program's name and a brief idea of what it does.> | ||||||
|  |     Copyright (C) <year>  <name of author> | ||||||
|  |  | ||||||
|  |     This program is free software: you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation, either version 3 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  |  | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  |  | ||||||
|  |     You should have received a copy of the GNU General Public License | ||||||
|  |     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | Also add information on how to contact you by electronic and paper mail. | ||||||
|  |  | ||||||
|  |   If the program does terminal interaction, make it output a short | ||||||
|  | notice like this when it starts in an interactive mode: | ||||||
|  |  | ||||||
|  |     facho-signer  Copyright (C) 2021  Jovany Leandro G.C <bit4bit@riseup.net> | ||||||
|  |     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||||||
|  |     This is free software, and you are welcome to redistribute it | ||||||
|  |     under certain conditions; type `show c' for details. | ||||||
|  |  | ||||||
|  | The hypothetical commands `show w' and `show c' should show the appropriate | ||||||
|  | parts of the General Public License.  Of course, your program's commands | ||||||
|  | might be different; for a GUI interface, you would use an "about box". | ||||||
|  |  | ||||||
|  |   You should also get your employer (if you work as a programmer) or school, | ||||||
|  | if any, to sign a "copyright disclaimer" for the program, if necessary. | ||||||
|  | For more information on this, and how to apply and follow the GNU GPL, see | ||||||
|  | <https://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  |   The GNU General Public License does not permit incorporating your program | ||||||
|  | into proprietary programs.  If your program is a subroutine library, you | ||||||
|  | may consider it more useful to permit linking proprietary applications with | ||||||
|  | the library.  If this is what you want to do, use the GNU Lesser General | ||||||
|  | Public License instead of this License.  But first, please read | ||||||
|  | <https://www.gnu.org/licenses/why-not-lgpl.html>. | ||||||
							
								
								
									
										0
									
								
								experimental/facho-signer/ChangeLog
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								experimental/facho-signer/ChangeLog
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								experimental/facho-signer/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								experimental/facho-signer/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | SUBDIRS = src | ||||||
							
								
								
									
										0
									
								
								experimental/facho-signer/NEWS
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								experimental/facho-signer/NEWS
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								experimental/facho-signer/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								experimental/facho-signer/README
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								experimental/facho-signer/boostrap.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								experimental/facho-signer/boostrap.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | libtoolize -c --force | ||||||
|  | autoreconf --install --force | ||||||
							
								
								
									
										56
									
								
								experimental/facho-signer/configure.ac
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								experimental/facho-signer/configure.ac
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | #                                               -*- Autoconf -*- | ||||||
|  | # Process this file with autoconf to produce a configure script. | ||||||
|  |  | ||||||
|  | AC_PREREQ([2.71]) | ||||||
|  | AC_INIT([facho-signer], [0.0.1], [bit4bit@riseup.net]) | ||||||
|  | AM_INIT_AUTOMAKE | ||||||
|  | AC_CONFIG_SRCDIR([src/facho_signer.c]) | ||||||
|  | AC_CONFIG_HEADERS([config.h]) | ||||||
|  | AC_CONFIG_MACRO_DIRS([m4]) | ||||||
|  |  | ||||||
|  | # Checks for programs. | ||||||
|  | AC_PROG_CC | ||||||
|  |  | ||||||
|  | # Checks for libraries. | ||||||
|  | PKG_CHECK_MODULES([OPENSSL], [openssl]) | ||||||
|  | PKG_CHECK_MODULES([XMLSEC1], [xmlsec1-openssl], [ | ||||||
|  |                              AC_DEFINE([XMLSEC_CRYPTO_OPENSSL], [1], [enable crypto openssl]) | ||||||
|  |                              ]) | ||||||
|  | PKG_CHECK_MODULES([LZMA], [liblzma]) | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([xmlsec-crypto-dynamic-loading], | ||||||
|  |         AS_HELP_STRING([--enable-xmlsec-crypto-dynamic-loading], | ||||||
|  |         [enable crypto xmlsec dynamic loading]) | ||||||
|  |        ) | ||||||
|  |  | ||||||
|  | if test "x$enable_xmlsec_crypto_dynamic_loading" == xyes; then | ||||||
|  |   AC_DEFINE([XMLSEC_CRYPTO_DYNAMIC_LOADING], [1], [enable xmlsec crypto dynamic loading]) | ||||||
|  |   AC_CHECK_HEADER([ltdl.h], [ | ||||||
|  | 		AC_CHECK_LIB( | ||||||
|  | 			[ltdl], | ||||||
|  | 			[lt_dlopenext], | ||||||
|  | 			[LIBLTDL=-lltdl], | ||||||
|  | 			[LIBLTDL=] | ||||||
|  | 			) | ||||||
|  | 		], [ LIBLTDL= ]) | ||||||
|  |  | ||||||
|  | else | ||||||
|  |   AC_DEFINE([XMLSEC_NO_CRYPTO_DYNAMIC_LOADING], [1], [disable xmlsec crypto dynamic loading]) | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Checks for header files. | ||||||
|  | AC_CHECK_HEADERS([sys/time.h unistd.h]) | ||||||
|  |  | ||||||
|  | # Checks for typedefs, structures, and compiler characteristics. | ||||||
|  | AC_TYPE_SIZE_T | ||||||
|  |  | ||||||
|  | # Checks for library functions. | ||||||
|  | AC_FUNC_MALLOC | ||||||
|  | AC_CHECK_FUNCS([clock_gettime gethrtime gettimeofday memset strdup]) | ||||||
|  |  | ||||||
|  | # libtool | ||||||
|  |  | ||||||
|  | LT_INIT | ||||||
|  |  | ||||||
|  | AC_CONFIG_FILES([Makefile src/Makefile]) | ||||||
|  | AC_OUTPUT | ||||||
							
								
								
									
										12
									
								
								experimental/facho-signer/src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								experimental/facho-signer/src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | SOURCES = xades/xmlsec1/xmltree.c xades/xmlsec1/errors.c xades/templates.c xades/xades.c facho_signer.c | ||||||
|  |  | ||||||
|  | lib_LTLIBRARIES = libfachosigner.la | ||||||
|  | libfachosigner_la_SOURCES = $(LTDL_SOURCE_FILES) $(SOURCES) | ||||||
|  | libfachosigner_la_CFLAGS = $(OPENSSL_CFLAGS) $(XMLSEC1_CFLAGS) -DXMLSEC_NOT_CRYPTO_DYNAMIC_LOADING | ||||||
|  | libfachosigner_la_LDFLAGS = $(OPENSSL_LIBS) $(LIBLTDL) $(XMLSEC1_LIBS) | ||||||
|  |  | ||||||
|  | bin_PROGRAMS = facho_signer | ||||||
|  | facho_signer_SOURCES = main.c | ||||||
|  | facho_signer_CFLAGS = $(OPENSSL_CFLAGS) $(XMLSEC1_CFLAGS) -DXMLSEC_NOT_CRYPTO_DYNAMIC_LOADING | ||||||
|  | facho_signer_LDADD = libfachosigner.la | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								experimental/facho-signer/src/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								experimental/facho-signer/src/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | # facho-signer | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## guia | ||||||
|  |  | ||||||
|  | - http://xmlsoft.org/html/libxml-tree.html | ||||||
|  | - http://xmlsoft.org/html/libxml-xpath.html | ||||||
|  | - http://xmlsoft.org/examples/xpath1.c | ||||||
|  | - http://xmlsoft.org/tutorial/ar01s05.html | ||||||
|  | - https://www.aleksey.com/xmlsec/api/xmlsec-reference.html | ||||||
|  | - https://zakird.com/2013/10/13/certificate-parsing-with-openssl | ||||||
							
								
								
									
										371
									
								
								experimental/facho-signer/src/facho_signer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										371
									
								
								experimental/facho-signer/src/facho_signer.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,371 @@ | |||||||
|  | /** | ||||||
|  |  * This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
|  |  * this repository contains the full copyright notices and license terms. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "config.h" | ||||||
|  | #include "xades/xades.h" | ||||||
|  |  | ||||||
|  | #include <xmlsec/xmlsec.h> | ||||||
|  | #include <xmlsec/xmltree.h> | ||||||
|  | #include <xmlsec/xmldsig.h> | ||||||
|  | #include <xmlsec/templates.h> | ||||||
|  | #include <xmlsec/crypto.h> | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | #define xmlFachoPrintError(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) | ||||||
|  | #define xmlFachoPrintInfo(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__) | ||||||
|  |  | ||||||
|  | static const xmlChar ublExtensionDSigNs[] = "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"; | ||||||
|  | static const xmlChar policyIdDescription[] = "Política de firma para facturas electrónicas de la República de Colombia."; | ||||||
|  | static const xmlChar policyIdIdentifier[] = "https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf"; | ||||||
|  |    | ||||||
|  | // crea elemento /Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent | ||||||
|  | static xmlNodePtr | ||||||
|  | xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc); | ||||||
|  |  | ||||||
|  | // FeC requiere que el digest value del policy identifier sea | ||||||
|  | // apartir del contenido de la url. | ||||||
|  | static int | ||||||
|  | xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *, xmlSecBufferPtr); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) { | ||||||
|  |   xmlNodePtr qualifyingPropertiesNode = NULL; | ||||||
|  |   xmlNodePtr signedPropertiesNode = NULL; | ||||||
|  |   xmlNodePtr signedSignaturePropertiesNode = NULL; | ||||||
|  |   xmlNodePtr signingCertificateNode = NULL; | ||||||
|  |   xmlNodePtr signaturePolicyIdentifierNode = NULL; | ||||||
|  |   xmlNodePtr signaturePolicyIdNode = NULL; | ||||||
|  |   xmlNodePtr sigPolicyIdNode = NULL; | ||||||
|  |   xmlNodePtr sigPolicyHashNode = NULL; | ||||||
|  |   xmlNodePtr signerRoleNode = NULL; | ||||||
|  |   xmlNodePtr refNode = NULL; | ||||||
|  |   const xmlChar signedPropertiesId[] = "xmldsig-facho-signed-props"; | ||||||
|  |   const xmlChar signedPropertiesRef[] = "#xmldsig-facho-signed-props"; | ||||||
|  |    | ||||||
|  |   qualifyingPropertiesNode = xmlXadesTmplQualifyingPropertiesCreate(doc, signNode, BAD_CAST "xades-ref1"); | ||||||
|  |   if (  qualifyingPropertiesNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add QualifyingProperties node.\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   signedPropertiesNode = xmlXadesTmplAddSignedProperties(qualifyingPropertiesNode, signedPropertiesId); | ||||||
|  |   if ( signedPropertiesNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: xades failed to add signed properties node.\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   refNode = xmlSecTmplSignatureAddReference(signNode, | ||||||
|  |                                             xmlSecTransformSha256Id, | ||||||
|  |                                             BAD_CAST "xmldsig-facho-ref1", | ||||||
|  |                                             signedPropertiesRef, | ||||||
|  |                                             BAD_CAST "http://uri.etsi.org/01903#SignedProperties"); | ||||||
|  |   if ( refNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add reference to signature template xades.\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |   if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformInclC14NId) == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add enveloped transform to reference for xades\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const time_t now = time(NULL); | ||||||
|  |   signedSignaturePropertiesNode = xmlXadesTmplAddSignedSignatureProperties(signedPropertiesNode, localtime(&now)); | ||||||
|  |   if ( signedSignaturePropertiesNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: xades failed to add signed signature properties node.\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   signingCertificateNode = xmlXadesTmplAddSigningCertificate(signedSignaturePropertiesNode, xmlSecTransformSha256Id); | ||||||
|  |   if ( signingCertificateNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add SigningCertificate node \n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   signaturePolicyIdentifierNode = xmlXadesTmplAddSignaturePolicyIdentifier(signedSignaturePropertiesNode); | ||||||
|  |   if ( signaturePolicyIdentifierNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add PolicyIdentifier node\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   signaturePolicyIdNode = xmlXadesTmplAddSignaturePolicyId(signaturePolicyIdentifierNode); | ||||||
|  |   if ( signaturePolicyIdNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add SignaturePolicyId node.\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   sigPolicyIdNode = xmlXadesTmplAddSigPolicyId(signaturePolicyIdNode, policyIdIdentifier, policyIdDescription); | ||||||
|  |   if ( sigPolicyIdNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add SigPolicyId node.\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   sigPolicyHashNode = xmlXadesTmplAddSigPolicyHash(signaturePolicyIdNode, xmlSecTransformSha256Id); | ||||||
|  |   if ( sigPolicyHashNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add SigPolicyHash node.\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   signerRoleNode = xmlXadesTmplAddSignerRole(signedSignaturePropertiesNode, BAD_CAST "supplier"); | ||||||
|  |   if ( signerRoleNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add SignerRole node.\n"); | ||||||
|  |     goto fail; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |    | ||||||
|  |   return(0); | ||||||
|  |  fail: | ||||||
|  |   xmlUnlinkNode(qualifyingPropertiesNode); | ||||||
|  |   xmlFreeNode(qualifyingPropertiesNode); | ||||||
|  |   return(-1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlFachoInit() { | ||||||
|  |   xmlInitParser(); | ||||||
|  |   LIBXML_TEST_VERSION; | ||||||
|  |    | ||||||
|  |   if ( xmlSecInit() < 0 ) { | ||||||
|  |     xmlFachoPrintError("xmlsec initialization failed.\n"); | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( xmlSecCheckVersion() != 1 ) { | ||||||
|  |     xmlFachoPrintError("loaded xmlsec library version is not compatible.\n"); | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING | ||||||
|  |     if(xmlSecCryptoDLLoadLibrary( NULL ) < 0) { | ||||||
|  |         fprintf(stderr, "Error: unable to load default xmlsec-crypto library. Make sure\n" | ||||||
|  |                         "that you have it installed and check shared libraries path\n" | ||||||
|  |                         "(LD_LIBRARY_PATH and/or LTDL_LIBRARY_PATH) environment variables.\n"); | ||||||
|  |         return(-1);      | ||||||
|  |     } | ||||||
|  | #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */ | ||||||
|  |     | ||||||
|  |   if ( xmlSecCryptoAppInit(NULL) < 0 ) { | ||||||
|  |     xmlFachoPrintError("crypto initialization failed.\n"); | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( xmlSecCryptoInit() < 0 ) { | ||||||
|  |     xmlFachoPrintError("xmlsec-crypto initialization failed.\n"); | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlFachoShutdown() { | ||||||
|  |  | ||||||
|  |   if ( xmlSecCryptoShutdown() < 0 ) { | ||||||
|  |     xmlFachoPrintError("xmlSecCryptoShutdown failed.\n"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( xmlSecCryptoAppShutdown() < 0 ) { | ||||||
|  |     xmlFachoPrintError("xmlSecCryptoAppShutdown failed.\n"); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   if ( xmlSecShutdown() < 0 ) { | ||||||
|  |     xmlFachoPrintError("xmlsec shutdown failed.\n"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   xmlCleanupParser(); | ||||||
|  |   return(0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlFachoSignFile(FILE *out, const char *filename, const char *pkcs12name, const char *password) { | ||||||
|  |   xmlDocPtr doc = NULL; | ||||||
|  |   xmlNodePtr signNode = NULL; | ||||||
|  |   xmlNodePtr refNode = NULL; | ||||||
|  |   xmlNodePtr keyInfoNode = NULL; | ||||||
|  |   xmlNodePtr x509DataNode = NULL; | ||||||
|  |   xmlNodePtr node = NULL; | ||||||
|  |   xmlSecDSigCtxPtr dsigCtx = NULL; | ||||||
|  |   xmlXadesDSigCtxPtr xadesDsigCtx = NULL; | ||||||
|  |  | ||||||
|  |   int res = -1; | ||||||
|  |    | ||||||
|  |   if (filename == NULL) { | ||||||
|  |    return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   doc = xmlParseFile(filename); | ||||||
|  |   if ( (doc == NULL) || (xmlDocGetRootElement(doc) == NULL) ) { | ||||||
|  |     xmlFachoPrintError("error: unable to parse file %s\n", filename); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformInclC14NId, | ||||||
|  |                                        xmlSecTransformRsaSha256Id, NULL); | ||||||
|  |   if ( signNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to create signature template.\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   xmlAddChild(xmlDocGetRootElement(doc), signNode); | ||||||
|  |  | ||||||
|  |   refNode = xmlSecTmplSignatureAddReference(signNode, | ||||||
|  |                                             xmlSecTransformSha256Id, | ||||||
|  |                                             BAD_CAST "xmldsig-facho-ref0", // id | ||||||
|  |                                             BAD_CAST "", //uri | ||||||
|  |                                             NULL); //type | ||||||
|  |   if ( refNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add reference to signature template.\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |   if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add enveloped transform to reference\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   refNode = xmlSecTmplSignatureAddReference(signNode, | ||||||
|  |                                             xmlSecTransformSha256Id, | ||||||
|  |                                             BAD_CAST "xmldsig-facho-ref2", | ||||||
|  |                                             BAD_CAST "#xmldsig-facho-KeyInfo", | ||||||
|  |                                             NULL); | ||||||
|  |   if ( refNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add reference to signature template key-info.\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, BAD_CAST "xmldsig-facho-KeyInfo"); | ||||||
|  |   if ( keyInfoNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add key info.\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   x509DataNode = xmlSecTmplKeyInfoAddX509Data(keyInfoNode); | ||||||
|  |   if ( x509DataNode == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failde to add x509 DATA \n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( xmlSecTmplX509DataAddCertificate(x509DataNode) == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failde to add x509Certificate node\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   if ( xmlFachoTmplXadesCreate(doc, signNode) < 0 ){ | ||||||
|  |     xmlFachoPrintError("error: xmlFachoTmplXadesCreate failed.\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   dsigCtx = xmlSecDSigCtxCreate(NULL); | ||||||
|  |   if ( dsigCtx == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: dsig context creating failed\n"); | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // cargamos el archivo pkcs12 con llave privado y certificados x509 | ||||||
|  |   dsigCtx->signKey = xmlSecCryptoAppKeyLoad(pkcs12name, | ||||||
|  |                                             xmlSecKeyDataFormatPkcs12, | ||||||
|  |                                             password, | ||||||
|  |                                             NULL, NULL); | ||||||
|  |   if ( dsigCtx->signKey == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to load pkcs12\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   xmlXadesPolicyIdentifierCtx policyIdCtx; | ||||||
|  |  | ||||||
|  |   // por ahora el hash del identificador lo tomamos del pdf de la dian | ||||||
|  |   policyIdCtx.contentCallback = &xmlFachoPolicyIdentifierCtxFromFilename; | ||||||
|  |      | ||||||
|  |   xadesDsigCtx = xmlXadesDSigCtxCreate(dsigCtx, XADES_DIGEST_SHA256, &policyIdCtx); | ||||||
|  |   if ( xadesDsigCtx == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: xades context creating failed.\n"); | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // debe existir el elemento antes del firmado | ||||||
|  |   node = xmlFachoTmplUBLExtensionAddExtensionContent(doc); | ||||||
|  |   if ( node == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add UBLExtensions/UBLExtension/ExtensionContent\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   // realizar firma de documento | ||||||
|  |   if ( xmlXadesDSigCtxSign(xadesDsigCtx, signNode) < 0 ) { | ||||||
|  |     xmlFachoPrintError("error: signature failed\n"); | ||||||
|  |     goto done; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   xmlUnlinkNode(signNode); | ||||||
|  |   xmlSecAddChildNode(node, signNode); | ||||||
|  |  | ||||||
|  |   xmlDocDump(out, doc); | ||||||
|  |  | ||||||
|  |   res = 0; | ||||||
|  |  | ||||||
|  |  done: | ||||||
|  |   if ( xadesDsigCtx != NULL ) { | ||||||
|  |     xmlXadesDSigCtxDestroy(xadesDsigCtx); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( dsigCtx != NULL ) { | ||||||
|  |     xmlSecDSigCtxDestroy(dsigCtx); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( doc != NULL ) { | ||||||
|  |     xmlFreeDoc(doc); | ||||||
|  |   } | ||||||
|  |   return(res); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static xmlNodePtr | ||||||
|  | xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc) { | ||||||
|  |   xmlNodePtr node = NULL; | ||||||
|  |   xmlNodePtr parent = NULL; | ||||||
|  |   const xmlChar ublExtensionsName[] = "UBLExtensions"; | ||||||
|  |   const xmlChar ublExtensionName[] = "UBLExtension"; | ||||||
|  |   const xmlChar extensionContentName[] = "ExtensionContent"; | ||||||
|  |      | ||||||
|  |   parent = xmlSecFindNode(xmlDocGetRootElement(doc), ublExtensionsName, ublExtensionDSigNs); | ||||||
|  |   if ( parent == NULL ) { | ||||||
|  |     parent = xmlSecAddChild(xmlDocGetRootElement(doc), ublExtensionsName,  ublExtensionDSigNs); | ||||||
|  |     if ( parent == NULL ) { | ||||||
|  |       xmlFachoPrintError("error: failed to cleate UBLExtensions.\n"); | ||||||
|  |       return(NULL); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // adicionamos nuevo elemento UBLExtension | ||||||
|  |   node = xmlSecAddChild(parent, ublExtensionName, ublExtensionDSigNs); | ||||||
|  |   if ( node == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add UBLExtension\n"); | ||||||
|  |     xmlFreeNode(parent); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // adicionamos nuevo elemento ExtensionContent | ||||||
|  |   node = xmlSecAddChild(node, extensionContentName, ublExtensionDSigNs); | ||||||
|  |   if ( node == NULL ) { | ||||||
|  |     xmlFachoPrintError("error: failed to add ExtensionContent"); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(node); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *policyId, xmlSecBufferPtr buffer) { | ||||||
|  |   static unsigned char politicafirmav2[] = { | ||||||
|  |     /** | ||||||
|  |      * generado con https://github.com/Jamesits/bin2array | ||||||
|  |      */ | ||||||
|  | #include "politicafirmav2.c" | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   return xmlSecBufferAppend(buffer, politicafirmav2, sizeof(politicafirmav2)); | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								experimental/facho-signer/src/facho_signer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								experimental/facho-signer/src/facho_signer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | /** | ||||||
|  |  * This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
|  |  * this repository contains the full copyright notices and license terms. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef FACHO_SIGNER_H | ||||||
|  | #define FACHO_SIGNER_H | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlFachoInit(); | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlFachoShutdown(); | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlFachoSignFile(FILE *out, const char *filename, const char *pkcs12name, const char *password); | ||||||
|  |  | ||||||
|  | #endif /* FACHO_SIGNER_H */ | ||||||
							
								
								
									
										47
									
								
								experimental/facho-signer/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								experimental/facho-signer/src/main.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | /** | ||||||
|  |  * This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
|  |  * this repository contains the full copyright notices and license terms. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "xades/xades.h" | ||||||
|  | #include "facho_signer.h" | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static char *basename = NULL; | ||||||
|  |  | ||||||
|  | void usage(FILE *out); | ||||||
|  |  | ||||||
|  | int main(int argc, char *argv[]) { | ||||||
|  |   int exitStatus = EXIT_SUCCESS; | ||||||
|  |   basename = argv[0]; | ||||||
|  |    | ||||||
|  |   if (argc != 4) { | ||||||
|  |     usage(stderr); | ||||||
|  |     return(EXIT_FAILURE); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( xmlFachoInit() < 0 ) { | ||||||
|  |     fprintf(stderr, "initialization failed.\n"); | ||||||
|  |     return(EXIT_FAILURE); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( xmlFachoSignFile( stdout, argv[1], argv[2], argv[3] ) != 0 ) { | ||||||
|  |     fprintf(stderr, "fail to sign file\n"); | ||||||
|  |     exitStatus = EXIT_FAILURE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   xmlFachoShutdown();   | ||||||
|  |   return(exitStatus); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | usage(FILE *out) { | ||||||
|  |   fprintf(out, "%s: <factura.xml> <pc12> <password>\n", basename); | ||||||
|  |   fprintf(out, "%s", "Firmado electronico para facturacion en Colombia.\n" | ||||||
|  |           "Segun el documento (Anexo Técnico de Factura Electrónica de Venta – Versión 1.7.-2020).\n" | ||||||
|  |           "A considerar:\n" \ | ||||||
|  |           " * adiciona un nuevo elemento //ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent\n"); | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								experimental/facho-signer/src/politicafirmav2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								experimental/facho-signer/src/politicafirmav2.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										391
									
								
								experimental/facho-signer/src/xades/minunit.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										391
									
								
								experimental/facho-signer/src/xades/minunit.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,391 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2012 David Siñuela Pastor, siu.4coders@gmail.com | ||||||
|  |  *  | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  *  | ||||||
|  |  * The above copyright notice and this permission notice shall be | ||||||
|  |  * included in all copies or substantial portions of the Software. | ||||||
|  |  *  | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||||
|  |  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||||
|  |  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||||
|  |  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  | #ifndef MINUNIT_MINUNIT_H | ||||||
|  | #define MINUNIT_MINUNIT_H | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | 	extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) | ||||||
|  | #include <Windows.h> | ||||||
|  | #if defined(_MSC_VER) && _MSC_VER < 1900 | ||||||
|  |   #define snprintf _snprintf | ||||||
|  |   #define __func__ __FUNCTION__ | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) | ||||||
|  |  | ||||||
|  | /* Change POSIX C SOURCE version for pure c99 compilers */ | ||||||
|  | #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L | ||||||
|  | #undef _POSIX_C_SOURCE | ||||||
|  | #define _POSIX_C_SOURCE 200112L | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <unistd.h>	/* POSIX flags */ | ||||||
|  | #include <time.h>	/* clock_gettime(), time() */ | ||||||
|  | #include <sys/time.h>	/* gethrtime(), gettimeofday() */ | ||||||
|  | #include <sys/resource.h> | ||||||
|  | #include <sys/times.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #if defined(__MACH__) && defined(__APPLE__) | ||||||
|  | #include <mach/mach.h> | ||||||
|  | #include <mach/mach_time.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if __GNUC__ >= 5 && !defined(__STDC_VERSION__) | ||||||
|  | #define __func__ __extension__ __FUNCTION__ | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #else | ||||||
|  | #error "Unable to define timers for an unknown OS." | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <math.h> | ||||||
|  |  | ||||||
|  | /*  Maximum length of last message */ | ||||||
|  | #define MINUNIT_MESSAGE_LEN 1024 | ||||||
|  | /*  Accuracy with which floats are compared */ | ||||||
|  | #define MINUNIT_EPSILON 1E-12 | ||||||
|  |  | ||||||
|  | /*  Misc. counters */ | ||||||
|  | static int minunit_run = 0; | ||||||
|  | static int minunit_assert = 0; | ||||||
|  | static int minunit_fail = 0; | ||||||
|  | static int minunit_status = 0; | ||||||
|  |  | ||||||
|  | /*  Timers */ | ||||||
|  | static double minunit_real_timer = 0; | ||||||
|  | static double minunit_proc_timer = 0; | ||||||
|  |  | ||||||
|  | /*  Last message */ | ||||||
|  | static char minunit_last_message[MINUNIT_MESSAGE_LEN]; | ||||||
|  |  | ||||||
|  | /*  Test setup and teardown function pointers */ | ||||||
|  | static void (*minunit_setup)(void) = NULL; | ||||||
|  | static void (*minunit_teardown)(void) = NULL; | ||||||
|  |  | ||||||
|  | /*  Definitions */ | ||||||
|  | #define MU_TEST(method_name) static void method_name(void) | ||||||
|  | #define MU_TEST_SUITE(suite_name) static void suite_name(void) | ||||||
|  |  | ||||||
|  | #define MU__SAFE_BLOCK(block) do {\ | ||||||
|  | 	block\ | ||||||
|  | } while(0) | ||||||
|  |  | ||||||
|  | /*  Run test suite and unset setup and teardown functions */ | ||||||
|  | #define MU_RUN_SUITE(suite_name) MU__SAFE_BLOCK(\ | ||||||
|  | 	suite_name();\ | ||||||
|  | 	minunit_setup = NULL;\ | ||||||
|  | 	minunit_teardown = NULL;\ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | /*  Configure setup and teardown functions */ | ||||||
|  | #define MU_SUITE_CONFIGURE(setup_fun, teardown_fun) MU__SAFE_BLOCK(\ | ||||||
|  | 	minunit_setup = setup_fun;\ | ||||||
|  | 	minunit_teardown = teardown_fun;\ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | /*  Test runner */ | ||||||
|  | #define MU_RUN_TEST(test) MU__SAFE_BLOCK(\ | ||||||
|  | 	if (minunit_real_timer==0 && minunit_proc_timer==0) {\ | ||||||
|  | 		minunit_real_timer = mu_timer_real();\ | ||||||
|  | 		minunit_proc_timer = mu_timer_cpu();\ | ||||||
|  | 	}\ | ||||||
|  | 	if (minunit_setup) (*minunit_setup)();\ | ||||||
|  | 	minunit_status = 0;\ | ||||||
|  | 	test();\ | ||||||
|  | 	minunit_run++;\ | ||||||
|  | 	if (minunit_status) {\ | ||||||
|  | 		minunit_fail++;\ | ||||||
|  | 		printf("F");\ | ||||||
|  | 		printf("\n%s\n", minunit_last_message);\ | ||||||
|  | 	}\ | ||||||
|  | 	fflush(stdout);\ | ||||||
|  | 	if (minunit_teardown) (*minunit_teardown)();\ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | /*  Report */ | ||||||
|  | #define MU_REPORT() MU__SAFE_BLOCK(\ | ||||||
|  | 	double minunit_end_real_timer;\ | ||||||
|  | 	double minunit_end_proc_timer;\ | ||||||
|  | 	printf("\n\n%d tests, %d assertions, %d failures\n", minunit_run, minunit_assert, minunit_fail);\ | ||||||
|  | 	minunit_end_real_timer = mu_timer_real();\ | ||||||
|  | 	minunit_end_proc_timer = mu_timer_cpu();\ | ||||||
|  | 	printf("\nFinished in %.8f seconds (real) %.8f seconds (proc)\n\n",\ | ||||||
|  | 		minunit_end_real_timer - minunit_real_timer,\ | ||||||
|  | 		minunit_end_proc_timer - minunit_proc_timer);\ | ||||||
|  | ) | ||||||
|  | #define MU_EXIT_CODE minunit_fail | ||||||
|  |  | ||||||
|  | /*  Assertions */ | ||||||
|  | #define mu_check(test) MU__SAFE_BLOCK(\ | ||||||
|  | 	minunit_assert++;\ | ||||||
|  | 	if (!(test)) {\ | ||||||
|  | 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, #test);\ | ||||||
|  | 		minunit_status = 1;\ | ||||||
|  | 		return;\ | ||||||
|  | 	} else {\ | ||||||
|  | 		printf(".");\ | ||||||
|  | 	}\ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #define mu_fail(message) MU__SAFE_BLOCK(\ | ||||||
|  | 	minunit_assert++;\ | ||||||
|  | 	snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, message);\ | ||||||
|  | 	minunit_status = 1;\ | ||||||
|  | 	return;\ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #define mu_assert(test, message) MU__SAFE_BLOCK(\ | ||||||
|  | 	minunit_assert++;\ | ||||||
|  | 	if (!(test)) {\ | ||||||
|  | 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, message);\ | ||||||
|  | 		minunit_status = 1;\ | ||||||
|  | 		return;\ | ||||||
|  | 	} else {\ | ||||||
|  | 		printf(".");\ | ||||||
|  | 	}\ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #define mu_assert_int_eq(expected, result) MU__SAFE_BLOCK(\ | ||||||
|  | 	int minunit_tmp_e;\ | ||||||
|  | 	int minunit_tmp_r;\ | ||||||
|  | 	minunit_assert++;\ | ||||||
|  | 	minunit_tmp_e = (expected);\ | ||||||
|  | 	minunit_tmp_r = (result);\ | ||||||
|  | 	if (minunit_tmp_e != minunit_tmp_r) {\ | ||||||
|  | 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %d expected but was %d", __func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r);\ | ||||||
|  | 		minunit_status = 1;\ | ||||||
|  | 		return;\ | ||||||
|  | 	} else {\ | ||||||
|  | 		printf(".");\ | ||||||
|  | 	}\ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #define mu_assert_double_eq(expected, result) MU__SAFE_BLOCK(\ | ||||||
|  | 	double minunit_tmp_e;\ | ||||||
|  | 	double minunit_tmp_r;\ | ||||||
|  | 	minunit_assert++;\ | ||||||
|  | 	minunit_tmp_e = (expected);\ | ||||||
|  | 	minunit_tmp_r = (result);\ | ||||||
|  | 	if (fabs(minunit_tmp_e-minunit_tmp_r) > MINUNIT_EPSILON) {\ | ||||||
|  | 		int minunit_significant_figures = 1 - log10(MINUNIT_EPSILON);\ | ||||||
|  | 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %.*g expected but was %.*g", __func__, __FILE__, __LINE__, minunit_significant_figures, minunit_tmp_e, minunit_significant_figures, minunit_tmp_r);\ | ||||||
|  | 		minunit_status = 1;\ | ||||||
|  | 		return;\ | ||||||
|  | 	} else {\ | ||||||
|  | 		printf(".");\ | ||||||
|  | 	}\ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #define mu_assert_string_eq(expected, result) MU__SAFE_BLOCK(\ | ||||||
|  | 	const char* minunit_tmp_e = expected;\ | ||||||
|  | 	const char* minunit_tmp_r = result;\ | ||||||
|  | 	minunit_assert++;\ | ||||||
|  | 	if (!minunit_tmp_e) {\ | ||||||
|  | 		minunit_tmp_e = "<null pointer>";\ | ||||||
|  | 	}\ | ||||||
|  | 	if (!minunit_tmp_r) {\ | ||||||
|  | 		minunit_tmp_r = "<null pointer>";\ | ||||||
|  | 	}\ | ||||||
|  | 	if(strcmp(minunit_tmp_e, minunit_tmp_r)) {\ | ||||||
|  | 		snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: '%s' expected but was '%s'", __func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r);\ | ||||||
|  | 		minunit_status = 1;\ | ||||||
|  | 		return;\ | ||||||
|  | 	} else {\ | ||||||
|  | 		printf(".");\ | ||||||
|  | 	}\ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * The following two functions were written by David Robert Nadeau | ||||||
|  |  * from http://NadeauSoftware.com/ and distributed under the | ||||||
|  |  * Creative Commons Attribution 3.0 Unported License | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Returns the real time, in seconds, or -1.0 if an error occurred. | ||||||
|  |  * | ||||||
|  |  * Time is measured since an arbitrary and OS-dependent start time. | ||||||
|  |  * The returned real time is only useful for computing an elapsed time | ||||||
|  |  * between two calls to this function. | ||||||
|  |  */ | ||||||
|  | static double mu_timer_real(void) | ||||||
|  | { | ||||||
|  | #if defined(_WIN32) | ||||||
|  | 	/* Windows 2000 and later. ---------------------------------- */ | ||||||
|  | 	LARGE_INTEGER Time; | ||||||
|  | 	LARGE_INTEGER Frequency; | ||||||
|  | 	 | ||||||
|  | 	QueryPerformanceFrequency(&Frequency); | ||||||
|  | 	QueryPerformanceCounter(&Time); | ||||||
|  | 	 | ||||||
|  | 	Time.QuadPart *= 1000000; | ||||||
|  | 	Time.QuadPart /= Frequency.QuadPart; | ||||||
|  | 	 | ||||||
|  | 	return (double)Time.QuadPart / 1000000.0; | ||||||
|  |  | ||||||
|  | #elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__))) | ||||||
|  | 	/* HP-UX, Solaris. ------------------------------------------ */ | ||||||
|  | 	return (double)gethrtime( ) / 1000000000.0; | ||||||
|  |  | ||||||
|  | #elif defined(__MACH__) && defined(__APPLE__) | ||||||
|  | 	/* OSX. ----------------------------------------------------- */ | ||||||
|  | 	static double timeConvert = 0.0; | ||||||
|  | 	if ( timeConvert == 0.0 ) | ||||||
|  | 	{ | ||||||
|  | 		mach_timebase_info_data_t timeBase; | ||||||
|  | 		(void)mach_timebase_info( &timeBase ); | ||||||
|  | 		timeConvert = (double)timeBase.numer / | ||||||
|  | 			(double)timeBase.denom / | ||||||
|  | 			1000000000.0; | ||||||
|  | 	} | ||||||
|  | 	return (double)mach_absolute_time( ) * timeConvert; | ||||||
|  |  | ||||||
|  | #elif defined(_POSIX_VERSION) | ||||||
|  | 	/* POSIX. --------------------------------------------------- */ | ||||||
|  | 	struct timeval tm; | ||||||
|  | #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) | ||||||
|  | 	{ | ||||||
|  | 		struct timespec ts; | ||||||
|  | #if defined(CLOCK_MONOTONIC_PRECISE) | ||||||
|  | 		/* BSD. --------------------------------------------- */ | ||||||
|  | 		const clockid_t id = CLOCK_MONOTONIC_PRECISE; | ||||||
|  | #elif defined(CLOCK_MONOTONIC_RAW) | ||||||
|  | 		/* Linux. ------------------------------------------- */ | ||||||
|  | 		const clockid_t id = CLOCK_MONOTONIC_RAW; | ||||||
|  | #elif defined(CLOCK_HIGHRES) | ||||||
|  | 		/* Solaris. ----------------------------------------- */ | ||||||
|  | 		const clockid_t id = CLOCK_HIGHRES; | ||||||
|  | #elif defined(CLOCK_MONOTONIC) | ||||||
|  | 		/* AIX, BSD, Linux, POSIX, Solaris. ----------------- */ | ||||||
|  | 		const clockid_t id = CLOCK_MONOTONIC; | ||||||
|  | #elif defined(CLOCK_REALTIME) | ||||||
|  | 		/* AIX, BSD, HP-UX, Linux, POSIX. ------------------- */ | ||||||
|  | 		const clockid_t id = CLOCK_REALTIME; | ||||||
|  | #else | ||||||
|  | 		const clockid_t id = (clockid_t)-1;	/* Unknown. */ | ||||||
|  | #endif /* CLOCK_* */ | ||||||
|  | 		if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 ) | ||||||
|  | 			return (double)ts.tv_sec + | ||||||
|  | 				(double)ts.tv_nsec / 1000000000.0; | ||||||
|  | 		/* Fall thru. */ | ||||||
|  | 	} | ||||||
|  | #endif /* _POSIX_TIMERS */ | ||||||
|  |  | ||||||
|  | 	/* AIX, BSD, Cygwin, HP-UX, Linux, OSX, POSIX, Solaris. ----- */ | ||||||
|  | 	gettimeofday( &tm, NULL ); | ||||||
|  | 	return (double)tm.tv_sec + (double)tm.tv_usec / 1000000.0; | ||||||
|  | #else | ||||||
|  | 	return -1.0;		/* Failed. */ | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Returns the amount of CPU time used by the current process, | ||||||
|  |  * in seconds, or -1.0 if an error occurred. | ||||||
|  |  */ | ||||||
|  | static double mu_timer_cpu(void) | ||||||
|  | { | ||||||
|  | #if defined(_WIN32) | ||||||
|  | 	/* Windows -------------------------------------------------- */ | ||||||
|  | 	FILETIME createTime; | ||||||
|  | 	FILETIME exitTime; | ||||||
|  | 	FILETIME kernelTime; | ||||||
|  | 	FILETIME userTime; | ||||||
|  |  | ||||||
|  | 	/* This approach has a resolution of 1/64 second. Unfortunately, Windows' API does not offer better */ | ||||||
|  | 	if ( GetProcessTimes( GetCurrentProcess( ), | ||||||
|  | 		&createTime, &exitTime, &kernelTime, &userTime ) != 0 ) | ||||||
|  | 	{ | ||||||
|  | 		ULARGE_INTEGER userSystemTime; | ||||||
|  | 		memcpy(&userSystemTime, &userTime, sizeof(ULARGE_INTEGER)); | ||||||
|  | 		return (double)userSystemTime.QuadPart / 10000000.0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) | ||||||
|  | 	/* AIX, BSD, Cygwin, HP-UX, Linux, OSX, and Solaris --------- */ | ||||||
|  |  | ||||||
|  | #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) | ||||||
|  | 	/* Prefer high-res POSIX timers, when available. */ | ||||||
|  | 	{ | ||||||
|  | 		clockid_t id; | ||||||
|  | 		struct timespec ts; | ||||||
|  | #if _POSIX_CPUTIME > 0 | ||||||
|  | 		/* Clock ids vary by OS.  Query the id, if possible. */ | ||||||
|  | 		if ( clock_getcpuclockid( 0, &id ) == -1 ) | ||||||
|  | #endif | ||||||
|  | #if defined(CLOCK_PROCESS_CPUTIME_ID) | ||||||
|  | 			/* Use known clock id for AIX, Linux, or Solaris. */ | ||||||
|  | 			id = CLOCK_PROCESS_CPUTIME_ID; | ||||||
|  | #elif defined(CLOCK_VIRTUAL) | ||||||
|  | 			/* Use known clock id for BSD or HP-UX. */ | ||||||
|  | 			id = CLOCK_VIRTUAL; | ||||||
|  | #else | ||||||
|  | 			id = (clockid_t)-1; | ||||||
|  | #endif | ||||||
|  | 		if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 ) | ||||||
|  | 			return (double)ts.tv_sec + | ||||||
|  | 				(double)ts.tv_nsec / 1000000000.0; | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(RUSAGE_SELF) | ||||||
|  | 	{ | ||||||
|  | 		struct rusage rusage; | ||||||
|  | 		if ( getrusage( RUSAGE_SELF, &rusage ) != -1 ) | ||||||
|  | 			return (double)rusage.ru_utime.tv_sec + | ||||||
|  | 				(double)rusage.ru_utime.tv_usec / 1000000.0; | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(_SC_CLK_TCK) | ||||||
|  | 	{ | ||||||
|  | 		const double ticks = (double)sysconf( _SC_CLK_TCK ); | ||||||
|  | 		struct tms tms; | ||||||
|  | 		if ( times( &tms ) != (clock_t)-1 ) | ||||||
|  | 			return (double)tms.tms_utime / ticks; | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(CLOCKS_PER_SEC) | ||||||
|  | 	{ | ||||||
|  | 		clock_t cl = clock( ); | ||||||
|  | 		if ( cl != (clock_t)-1 ) | ||||||
|  | 			return (double)cl / (double)CLOCKS_PER_SEC; | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	return -1;		/* Failed. */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif /* MINUNIT_MINUNIT_H */ | ||||||
							
								
								
									
										13
									
								
								experimental/facho-signer/src/xades/minunit_ext.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								experimental/facho-signer/src/xades/minunit_ext.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | #ifndef MINUNIT_EXT_H | ||||||
|  |  | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "minunit.h" | ||||||
|  |  | ||||||
|  | // cuando escribe esto el compilar me arrojo que si no era | ||||||
|  | // mejor usar mu_assert_string_eq increble a  | ||||||
|  | //int mu_assert_string_equals(const char *a, const char *b) { | ||||||
|  | //  return mu_assert(strcmp(a, b) == 0, "string not equals"); | ||||||
|  | //} | ||||||
|  |  | ||||||
|  | #endif //MINUNIT_EXT_H | ||||||
							
								
								
									
										456
									
								
								experimental/facho-signer/src/xades/templates.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										456
									
								
								experimental/facho-signer/src/xades/templates.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,456 @@ | |||||||
|  | /** | ||||||
|  |  * This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
|  |  * this repository contains the full copyright notices and license terms. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "xades.h" | ||||||
|  |  | ||||||
|  | #include <xmlsec/templates.h> | ||||||
|  |  | ||||||
|  | #include <time.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | static const xmlChar xmlXadesNodeQualifyingProperties[] = "QualifyingProperties"; | ||||||
|  | static const xmlChar xmlXadesNodeSignedProperties[] = "SignedProperties"; | ||||||
|  |  | ||||||
|  | static const xmlChar xmlXadesNodeSignedSignatureProperties[] = "SignedSignatureProperties"; | ||||||
|  | static const xmlChar xmlXadesNodeSigningTime[] = "SigningTime"; | ||||||
|  | static const xmlChar xmlXadesNodeSigningCertificate[] = "SigningCertificate"; | ||||||
|  | static const xmlChar xmlXadesNodeCert[] = "Cert"; | ||||||
|  | static const xmlChar xmlXadesNodeCertDigest[] = "CertDigest"; | ||||||
|  | static const xmlChar xmlXadesNodeSignaturePolicyIdentifier[] = "SignaturePolicyIdentifier"; | ||||||
|  | static const xmlChar xmlXadesNodeSignaturePolicyId[] = "SignaturePolicyId"; | ||||||
|  | static const xmlChar xmlXadesNodeSigPolicyId[] = "SigPolicyId"; | ||||||
|  | static const xmlChar xmlXadesNodeIdentifier[] = "Identifier"; | ||||||
|  | static const xmlChar xmlXadesNodeDescription[] = "Description"; | ||||||
|  | static const xmlChar xmlXadesNodeSigPolicyHash[] = "SigPolicyHash"; | ||||||
|  |  | ||||||
|  | static const xmlChar xmlXadesNodeSignerRole[] = "SignerRole"; | ||||||
|  | static const xmlChar xmlXadesNodeClaimedRoles[] = "ClaimedRoles"; | ||||||
|  | static const xmlChar xmlXadesNodeClaimedRole[] = "ClaimedRole"; | ||||||
|  | static const xmlChar xmlXadesNodeIssuerSerial[] = "IssuerSerial"; | ||||||
|  | static const xmlChar xmlXadesNodeX509IssuerName[] = "X509IssuerName"; | ||||||
|  | static const xmlChar xmlXadesNodeX509IssuerNumber[] = "X509IssuerNumber"; | ||||||
|  |    | ||||||
|  | static const xmlChar xmlXadesDSigNs[] = "http://uri.etsi.org/01903/v1.3.2#"; | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesAddChildRecursiveNs(xmlNodePtr startNode, const xmlChar* path, const xmlChar* nsPrefix) { | ||||||
|  |   char *curToken; | ||||||
|  |   char* cpath = strdup((char *)path); | ||||||
|  |   char* savePtr; | ||||||
|  |   xmlNodePtr curNode = NULL; | ||||||
|  |   xmlNodePtr parentNode = startNode; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   curToken = strtok_r(cpath, "/", &savePtr); | ||||||
|  |   while(curToken != NULL) { | ||||||
|  |     curNode = xmlSecFindChild(parentNode, BAD_CAST curToken, nsPrefix); | ||||||
|  |     if (curNode == NULL) { | ||||||
|  |       curNode = xmlSecAddChild(parentNode, BAD_CAST curToken, nsPrefix); | ||||||
|  |       if (curNode == NULL) { | ||||||
|  |         xmlXadesInternalError("xmlSecAddChild(%s)", curToken); | ||||||
|  |         return(NULL); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     parentNode = curNode; | ||||||
|  |  | ||||||
|  |     curToken = strtok_r(NULL, "/", &savePtr); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   free(cpath); | ||||||
|  |   return(curNode); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplQualifyingPropertiesCreate(xmlDocPtr doc, xmlNodePtr signatureNode, const xmlChar *id) { | ||||||
|  |   xmlNodePtr objectNode; | ||||||
|  |   xmlNodePtr qualifyingPropertiesNode; | ||||||
|  |  | ||||||
|  |   xmlNewGlobalNs(doc, xmlXadesDSigNs, BAD_CAST "xades"); | ||||||
|  |  | ||||||
|  |   objectNode = xmlSecTmplSignatureAddObject(signatureNode, NULL, NULL, NULL); | ||||||
|  |   if (objectNode == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecTmplSignatureAddObject(signatureNode)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   qualifyingPropertiesNode = xmlSecAddChild(objectNode, xmlXadesNodeQualifyingProperties, xmlXadesDSigNs); | ||||||
|  |   if (qualifyingPropertiesNode == NULL) { | ||||||
|  |     xmlXadesXmlError2("xmlNewDocNode", NULL, "node=%s", xmlXadesErrorsSafeString(xmlXadesNodeQualifyingProperties)); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (id != NULL) { | ||||||
|  |     xmlSetProp(qualifyingPropertiesNode, BAD_CAST "Id", id); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(qualifyingPropertiesNode); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplQualifyingPropertiesCreateNsPref(xmlDocPtr doc, const xmlChar* id, const xmlChar* nsPrefix) { | ||||||
|  |   xmlNodePtr qualifyingPropertiesNode; | ||||||
|  |   xmlNsPtr ns; | ||||||
|  |  | ||||||
|  |   // crear nodo | ||||||
|  |   qualifyingPropertiesNode = xmlNewDocNode(doc, NULL, xmlXadesNodeQualifyingProperties, NULL); | ||||||
|  |   if (qualifyingPropertiesNode == NULL) { | ||||||
|  |     xmlXadesXmlError2("xmlNewDocNode", NULL, "node=%s", xmlXadesErrorsSafeString(xmlXadesNodeQualifyingProperties)); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // crear namespace y asignar | ||||||
|  |   ns = xmlNewNs(qualifyingPropertiesNode, xmlXadesDSigNs, nsPrefix); | ||||||
|  |   if (ns == NULL) { | ||||||
|  |     xmlXadesXmlError2("xmlNewNs", NULL, | ||||||
|  |                    "ns=%s", xmlXadesErrorsSafeString(xmlXadesDSigNs)); | ||||||
|  |     xmlFreeNode(qualifyingPropertiesNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |   xmlSetNs(qualifyingPropertiesNode, ns); | ||||||
|  |  | ||||||
|  |   if (id != NULL) { | ||||||
|  |     xmlSetProp(qualifyingPropertiesNode, BAD_CAST "Id", id); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   | ||||||
|  |   return (qualifyingPropertiesNode); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignedProperties(xmlNodePtr qualifyingPropertiesNode, const xmlChar* id) { | ||||||
|  |   xmlNodePtr cur; | ||||||
|  |  | ||||||
|  |   xmlXadesAssert2(qualifyingPropertiesNode != NULL, NULL); | ||||||
|  |    | ||||||
|  |   cur = xmlSecAddChild(qualifyingPropertiesNode, xmlXadesNodeSignedProperties, xmlXadesDSigNs); | ||||||
|  |   if (cur == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignedProperties)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (id != NULL) { | ||||||
|  |     xmlSetProp(cur, BAD_CAST "Id", id); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(cur); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignedSignatureProperties(xmlNodePtr signedPropertiesNode, struct tm* signingTime) { | ||||||
|  |   xmlNodePtr cur; | ||||||
|  |   xmlNodePtr node; | ||||||
|  |  | ||||||
|  |   xmlXadesAssert2(signedPropertiesNode != NULL, NULL); | ||||||
|  |    | ||||||
|  |   // add SignedSignatureProperties | ||||||
|  |   node = xmlSecAddChild(signedPropertiesNode, xmlXadesNodeSignedSignatureProperties, xmlXadesDSigNs); | ||||||
|  |   if (node == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignedSignatureProperties)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // add SignigTime | ||||||
|  |   cur = xmlSecAddChild(node, xmlXadesNodeSigningTime, xmlXadesDSigNs); | ||||||
|  |   if (cur == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigningTime)", NULL); | ||||||
|  |     xmlFreeNode(node); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   { | ||||||
|  |     int ret; | ||||||
|  |     char strtime[200]; | ||||||
|  |  | ||||||
|  |     if (strftime(strtime, sizeof(strtime), "%Y-%m-%dT%T", signingTime) == 0) { | ||||||
|  |       xmlXadesInternalError("strftime", NULL); | ||||||
|  |       xmlFreeNode(cur); | ||||||
|  |       xmlFreeNode(node); | ||||||
|  |       return(NULL); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ret = xmlSecNodeEncodeAndSetContent(cur, BAD_CAST strtime); | ||||||
|  |     if (ret < 0) { | ||||||
|  |       xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); | ||||||
|  |       xmlFreeNode(cur); | ||||||
|  |       xmlFreeNode(node); | ||||||
|  |       return(NULL); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(node); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSigningCertificate(xmlNodePtr signedSignaturePropertiesNode, xmlSecTransformId digestMethodId) { | ||||||
|  |   xmlNodePtr node; | ||||||
|  |  | ||||||
|  |   xmlXadesAssert2(signedSignaturePropertiesNode != NULL, NULL); | ||||||
|  |   if (xmlSecFindChild(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, xmlXadesDSigNs) != NULL) { | ||||||
|  |     xmlXadesNodeAlreadyPresentError(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   node = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, xmlXadesDSigNs); | ||||||
|  |   if (node == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSigningCertificate)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(node); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddCert(xmlNodePtr signingCertificateNode) { | ||||||
|  |   xmlNodePtr certNode; | ||||||
|  |  | ||||||
|  |   xmlXadesAssert2(signingCertificateNode != NULL, NULL); | ||||||
|  |  | ||||||
|  |   certNode = xmlSecAddChild(signingCertificateNode, xmlXadesNodeCert, xmlXadesDSigNs); | ||||||
|  |   if (certNode == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeCert)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(certNode); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddCertDigest(xmlNodePtr certNode, const xmlChar *digestMethod, const xmlChar *digestValue) { | ||||||
|  |   xmlNodePtr node; | ||||||
|  |  | ||||||
|  |   xmlXadesAssert2(certNode != NULL, NULL); | ||||||
|  |  | ||||||
|  |   node = xmlSecAddChild(certNode, xmlXadesNodeCertDigest, xmlXadesDSigNs); | ||||||
|  |   if ( node == NULL ) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeCertDigest)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( xmlXadesTmplAddDigest(node, digestMethod, digestValue) == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlXadesTmplAddDigest(node, digestMethodId)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(certNode); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignaturePolicyIdentifier(xmlNodePtr signedSignaturePropertiesNode) { | ||||||
|  |   xmlNodePtr cur; | ||||||
|  |  | ||||||
|  |   xmlXadesAssert2(signedSignaturePropertiesNode != NULL, NULL); | ||||||
|  |  | ||||||
|  |   cur = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSignaturePolicyIdentifier, xmlXadesDSigNs); | ||||||
|  |   if (cur == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSignaturePolicyIdentifier)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(cur); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignaturePolicyId(xmlNodePtr signaturePolicyIdentifierNode) { | ||||||
|  |   xmlNodePtr cur; | ||||||
|  |  | ||||||
|  |   xmlXadesAssert2(signaturePolicyIdentifierNode != NULL, NULL); | ||||||
|  |  | ||||||
|  |   cur = xmlSecAddChild(signaturePolicyIdentifierNode, xmlXadesNodeSignaturePolicyId, xmlXadesDSigNs); | ||||||
|  |   if (cur == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlsecAddChild(cur)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(cur); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSigPolicyId(xmlNodePtr signaturePolicyId, const xmlChar* identifier, const xmlChar *description) { | ||||||
|  |   xmlNodePtr sigPolicyIdNode; | ||||||
|  |   xmlNodePtr node; | ||||||
|  |   int ret; | ||||||
|  |    | ||||||
|  |   sigPolicyIdNode = xmlSecAddChild(signaturePolicyId, xmlXadesNodeSigPolicyId, xmlXadesDSigNs); | ||||||
|  |   if (sigPolicyIdNode == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigPolicyId)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   node = xmlSecAddChild(sigPolicyIdNode, xmlXadesNodeIdentifier, xmlXadesDSigNs); | ||||||
|  |   if (node == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeIdentifier)", NULL); | ||||||
|  |     xmlFreeNode(sigPolicyIdNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ret = xmlSecNodeEncodeAndSetContent(node, identifier); | ||||||
|  |   if (ret < 0) { | ||||||
|  |     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); | ||||||
|  |     xmlFreeNode(sigPolicyIdNode); | ||||||
|  |     xmlFreeNode(node); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   node = xmlSecAddChild(sigPolicyIdNode, xmlXadesNodeDescription, xmlXadesDSigNs); | ||||||
|  |   if (node == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeDescription)", NULL); | ||||||
|  |     xmlFreeNode(sigPolicyIdNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ret = xmlSecNodeEncodeAndSetContent(node, description); | ||||||
|  |   if (ret < 0) { | ||||||
|  |     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); | ||||||
|  |     xmlFreeNode(sigPolicyIdNode); | ||||||
|  |     xmlFreeNode(node); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(sigPolicyIdNode); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSigPolicyHash(xmlNodePtr parentNode, xmlSecTransformId digestMethodId) { | ||||||
|  |   xmlNodePtr node; | ||||||
|  |   xmlXadesAssert2(parentNode != NULL, NULL); | ||||||
|  |  | ||||||
|  |   //add policyHash | ||||||
|  |   node = xmlSecAddChild(parentNode, xmlXadesNodeSigPolicyHash, xmlXadesDSigNs); | ||||||
|  |   if (node == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigPolicyHash)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( xmlXadesTmplAddDigest(node, digestMethodId->href, NULL) == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlXadesTmplAddDigest(node, digestMethodId)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return node; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // MACHETE(bit4bit) como usar SecTransform para almacenar el digest | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddDigest(xmlNodePtr parentNode, const xmlChar *digestMethod, const xmlChar *digestValue) { | ||||||
|  |   xmlNodePtr node; | ||||||
|  |    | ||||||
|  |   xmlXadesAssert2(parentNode != NULL, NULL); | ||||||
|  |  | ||||||
|  |   if ( digestMethod != NULL ) { | ||||||
|  |     node = xmlSecAddChild(parentNode, xmlSecNodeDigestMethod, xmlSecDSigNs); | ||||||
|  |     if (node == NULL) { | ||||||
|  |       xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestMethod)", NULL); | ||||||
|  |       return(NULL); | ||||||
|  |     } | ||||||
|  |     if (xmlSetProp(node, xmlSecAttrAlgorithm, digestMethod) == NULL) { | ||||||
|  |       xmlXadesXmlError2("xmlSetProp", NULL, | ||||||
|  |                         "name=%s", xmlXadesErrorsSafeString(xmlSecAttrAlgorithm)); | ||||||
|  |       xmlUnlinkNode(node); | ||||||
|  |       xmlFreeNode(node); | ||||||
|  |       return(NULL); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( digestValue != NULL ) { | ||||||
|  |     node = xmlSecAddChild(parentNode, xmlSecNodeDigestValue, xmlSecDSigNs); | ||||||
|  |     if (node == NULL) { | ||||||
|  |       xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestValue)", NULL); | ||||||
|  |       return(NULL); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if (xmlSecNodeEncodeAndSetContent(node, digestValue) < 0) { | ||||||
|  |       xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); | ||||||
|  |       return(NULL); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   return parentNode; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignerRole(xmlNodePtr signedSignaturePropertiesNode, const xmlChar* role) { | ||||||
|  |   xmlNodePtr signerRoleNode; | ||||||
|  |   xmlNodePtr claimedRolesNode; | ||||||
|  |   xmlNodePtr claimedRoleNode; | ||||||
|  |   int ret; | ||||||
|  |  | ||||||
|  |   signerRoleNode = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSignerRole, xmlXadesDSigNs); | ||||||
|  |   if (signerRoleNode == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignerRole)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   claimedRolesNode = xmlSecAddChild(signerRoleNode, xmlXadesNodeClaimedRoles, xmlXadesDSigNs); | ||||||
|  |   if (claimedRolesNode == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeClaimedRoles)", NULL); | ||||||
|  |     xmlUnlinkNode(signerRoleNode); | ||||||
|  |     xmlFreeNode(signerRoleNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   claimedRoleNode = xmlSecAddChild(claimedRolesNode, xmlXadesNodeClaimedRole, xmlXadesDSigNs); | ||||||
|  |   if (claimedRoleNode == NULL) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeClaimedRole)", NULL); | ||||||
|  |     xmlUnlinkNode(signerRoleNode); | ||||||
|  |     xmlFreeNode(signerRoleNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ret = xmlSecNodeEncodeAndSetContent(claimedRoleNode, role); | ||||||
|  |   if (ret < 0) { | ||||||
|  |     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); | ||||||
|  |     xmlUnlinkNode(signerRoleNode); | ||||||
|  |     xmlFreeNode(signerRoleNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(signerRoleNode); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddIssuerSerial(xmlNodePtr certNode, const xmlChar *issuerName, const xmlChar *issuerNumber) { | ||||||
|  |   xmlNodePtr issuerSerialNode; | ||||||
|  |   xmlNodePtr node; | ||||||
|  |  | ||||||
|  |   xmlXadesAssert2(certNode != NULL, NULL); | ||||||
|  |  | ||||||
|  |   issuerSerialNode = xmlSecAddChild(certNode, xmlXadesNodeIssuerSerial, xmlXadesDSigNs); | ||||||
|  |   if ( issuerSerialNode == NULL ) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(certNode, xmlXadesIssuerSerial)", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   node = xmlSecAddChild(issuerSerialNode, xmlXadesNodeX509IssuerName, xmlSecDSigNs); | ||||||
|  |   if ( node == NULL ) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeX509IssuerName)", NULL); | ||||||
|  |     xmlFreeNode(issuerSerialNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (xmlSecNodeEncodeAndSetContent(node, issuerName) < 0) { | ||||||
|  |     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); | ||||||
|  |     xmlUnlinkNode(issuerSerialNode); | ||||||
|  |     xmlFreeNode(issuerSerialNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   node = xmlSecAddChild(issuerSerialNode, xmlXadesNodeX509IssuerNumber, xmlSecDSigNs); | ||||||
|  |   if ( node == NULL ) { | ||||||
|  |     xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeX509IssuerNumber)", NULL); | ||||||
|  |     xmlFreeNode(issuerSerialNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (xmlSecNodeEncodeAndSetContent(node, issuerNumber) < 0) { | ||||||
|  |     xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL); | ||||||
|  |     xmlUnlinkNode(issuerSerialNode); | ||||||
|  |     xmlFreeNode(issuerSerialNode); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(issuerSerialNode); | ||||||
|  | } | ||||||
							
								
								
									
										301
									
								
								experimental/facho-signer/src/xades/xades.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										301
									
								
								experimental/facho-signer/src/xades/xades.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,301 @@ | |||||||
|  | /** | ||||||
|  |  * This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
|  |  * this repository contains the full copyright notices and license terms. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "config.h" | ||||||
|  |  | ||||||
|  | #include "xades.h" | ||||||
|  |  | ||||||
|  | #include <libxml/xpath.h> | ||||||
|  | #include <libxml/xpathInternals.h> | ||||||
|  | #include <openssl/x509.h> | ||||||
|  | #include <openssl/x509v3.h> | ||||||
|  | #include <openssl/bio.h> | ||||||
|  | #include <openssl/asn1.h> | ||||||
|  | #include <openssl/bn.h> | ||||||
|  |  | ||||||
|  | #include <xmlsec/buffer.h> | ||||||
|  | #include <xmlsec/app.h> | ||||||
|  | #include <xmlsec/transforms.h> | ||||||
|  | #include <xmlsec/keysdata.h> | ||||||
|  |  | ||||||
|  | #ifdef XMLSEC_NO_CRYPTO_DYNAMIC_LOADING | ||||||
|  | #include <xmlsec/openssl/x509.h> | ||||||
|  | #include <xmlsec/openssl/crypto.h> | ||||||
|  | #include <xmlsec/openssl/symbols.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <string.h> | ||||||
|  | #include <ctype.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static xmlChar * | ||||||
|  | xmlXadesSha256DigestValueInBase64(const unsigned char *message, size_t message_len); | ||||||
|  |  | ||||||
|  | static xmlNodePtr | ||||||
|  | xmlXadesXPathFirstElement(xmlDocPtr doc, const xmlChar *xpath); | ||||||
|  |  | ||||||
|  | xmlXadesDSigCtxPtr | ||||||
|  | xmlXadesDSigCtxCreate(xmlSecDSigCtxPtr dsigCtx, XADES_DIGEST_METHOD digestMethod, xmlXadesPolicyIdentifierCtxPtr policyCtx) { | ||||||
|  |   xmlXadesDSigCtxPtr ctx = NULL; | ||||||
|  |  | ||||||
|  |   ctx = malloc(sizeof(xmlXadesDSigCtx)); | ||||||
|  |   if ( ctx == NULL ) { | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ctx->dsigCtx = dsigCtx; | ||||||
|  |   ctx->digestMethod = digestMethod; | ||||||
|  |   ctx->policyCtx = policyCtx; | ||||||
|  |   return ctx; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlXadesDSigCtxSign(xmlXadesDSigCtxPtr ctx, xmlNodePtr signNode) { | ||||||
|  |   xmlNodePtr signingCertificateNode = NULL; | ||||||
|  |   xmlSecKeyDataPtr keyDataX509; | ||||||
|  |   xmlSecSize certsSize; | ||||||
|  |  | ||||||
|  |   signingCertificateNode = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//ds:Object/xades:QualifyingProperties//xades:SigningCertificate[1]"); | ||||||
|  |   if ( signingCertificateNode == NULL ) { | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   keyDataX509 = xmlSecKeyEnsureData(ctx->dsigCtx->signKey, xmlSecKeyDataX509Id); | ||||||
|  |   if ( keyDataX509 == NULL ) { | ||||||
|  |     xmlXadesInternalError("failed to get X509.\n", NULL); | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   certsSize = xmlSecOpenSSLKeyDataX509GetCertsSize(keyDataX509); | ||||||
|  |   for (xmlSecSize i = 0; i < certsSize; i++) { | ||||||
|  |     // calculamos el digest del certificado | ||||||
|  |     unsigned char md[EVP_MAX_MD_SIZE]; | ||||||
|  |     unsigned int md_n; | ||||||
|  |     // TODO(bit4bit) podemos obtener el digest de openssl por medio de la transformacion? o se puede usar la transformacion para generar el digest? | ||||||
|  |     xmlChar *digestMethod = NULL; | ||||||
|  |     EVP_MD *digest = NULL; | ||||||
|  |  | ||||||
|  |     switch(ctx->digestMethod) { | ||||||
|  |     case XADES_DIGEST_SHA256: | ||||||
|  |       digestMethod = (xmlChar *)xmlSecTransformSha256Id->href; | ||||||
|  |       digest = (EVP_MD *) EVP_sha256(); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       xmlXadesInternalError("xmlXadesDSigCtxSign not known how to handle digest method.\n", NULL); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     X509 *cert = xmlSecOpenSSLKeyDataX509GetCert(keyDataX509, i); | ||||||
|  |     if ( cert == NULL ) { | ||||||
|  |       xmlXadesInternalError("openssl: failed to get X509 cert.\n", NULL); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     X509_digest(cert, digest, md, &md_n); | ||||||
|  |     xmlChar *digestValue = xmlSecBase64Encode(md, md_n, 0); | ||||||
|  |  | ||||||
|  |     xmlNodePtr certNode = xmlXadesTmplAddCert(signingCertificateNode); | ||||||
|  |     if ( certNode == NULL ) { | ||||||
|  |       xmlXadesInternalError("xmlXadesTmplAddCert(signingCertificateNode)\n", NULL); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // adicionamos digest  | ||||||
|  |     xmlXadesTmplAddCertDigest(certNode, | ||||||
|  |                               digestMethod, | ||||||
|  |                               digestValue); | ||||||
|  |  | ||||||
|  |     char *issuerName = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); | ||||||
|  |  | ||||||
|  |     /* TODO(bit4bit) formatear? | ||||||
|  |     char *issuerNamePtr = issuerName; | ||||||
|  |      | ||||||
|  |     for(issuerNamePtr = strchr(issuerNamePtr, '/'); issuerNamePtr != NULL; issuerNamePtr = strchr(issuerNamePtr, '/')) { | ||||||
|  |       if (issuerNamePtr == issuerName) { | ||||||
|  |         issuerName += 1; | ||||||
|  |       } else { | ||||||
|  |         *issuerNamePtr = ','; | ||||||
|  |       } | ||||||
|  |       }*/ | ||||||
|  |  | ||||||
|  |     ASN1_INTEGER *serial = X509_get_serialNumber(cert); | ||||||
|  |     BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL); | ||||||
|  |     if ( bn == NULL ) { | ||||||
|  |       xmlXadesInternalError("unable to convert ASN1_INTEGER_to_BN to BN\n", NULL); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |     char *issuerNumber = BN_bn2dec(bn); | ||||||
|  |     if ( issuerNumber == NULL ) { | ||||||
|  |       xmlXadesInternalError("unable to convert BN to decimal string\n", NULL); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (xmlXadesTmplAddIssuerSerial(certNode, BAD_CAST issuerName, BAD_CAST issuerNumber) == NULL) { | ||||||
|  |       xmlXadesInternalError("xmlXadesTmplAddIssuerSerial", NULL); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |     BN_free(bn); | ||||||
|  |     OPENSSL_free(issuerNumber); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // digest de policy identifier | ||||||
|  |   xmlNodePtr sigPolicyId = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//xades:SigPolicyId/xades:Identifier[1]"); | ||||||
|  |   if ( sigPolicyId == NULL ) { | ||||||
|  |     xmlXadesInternalError("xmlXadesXPathFirstElement(xades:SigPolicyId/xades:Identifier\n", NULL); | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( ctx->policyCtx == NULL ) { | ||||||
|  |     xmlXadesInternalError("not found policy context.\n", NULL); | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( ctx->policyCtx != NULL ) { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     if ( ctx->policyCtx->contentCallback == NULL ) { | ||||||
|  |       xmlXadesInternalError("not found policy content callback.\n", NULL); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     xmlSecTransformCtxPtr transformCtx = xmlSecTransformCtxCreate(); | ||||||
|  |     if (transformCtx == NULL ) { | ||||||
|  |       xmlXadesInternalError("xmlSecTransformCtxCreate().\n", NULL); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // elemento del digest | ||||||
|  |     xmlNodePtr sigPolicyHashDigestMethod = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//xades:SigPolicyHash/ds:DigestMethod[1]"); | ||||||
|  |     if ( sigPolicyHashDigestMethod == NULL ) { | ||||||
|  |       xmlXadesInternalError("xmlXadesXPathFirstElement(xades:SigPolicyHash/xades:DigestMethod\n", NULL); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |     xmlSecTransformPtr transformPolicyDigestMethod = xmlSecTransformNodeRead(sigPolicyHashDigestMethod, | ||||||
|  |                                                                              xmlSecTransformUsageDigestMethod, | ||||||
|  |                                                                              transformCtx); | ||||||
|  |     if ( transformPolicyDigestMethod == NULL ) { | ||||||
|  |       xmlXadesInternalError("xmlSecTransformNodeRead\n", NULL); | ||||||
|  |       xmlFreeNode(sigPolicyHashDigestMethod); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if ( xmlSecTransformCheckId(transformPolicyDigestMethod, xmlSecTransformSha256Id) == 0 ) { | ||||||
|  |       xmlXadesInternalError("sigPolicyHash only support sha256 digest method .\n", NULL); | ||||||
|  |       xmlFreeNode(sigPolicyHashDigestMethod); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO(bit4bit) podemos usar xmlSecTransform para calcular el digest? | ||||||
|  |     xmlNodePtr sigPolicyHashNode = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//xades:SigPolicyHash[1]"); | ||||||
|  |     if ( sigPolicyHashNode == NULL ) { | ||||||
|  |       xmlXadesInternalError("failed to find sigPolicyHash node.\n", NULL); | ||||||
|  |       xmlFreeNode(sigPolicyHashDigestMethod); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // obtenemos contenido de la policy | ||||||
|  |     xmlChar *identifier = xmlNodeListGetString(signNode->doc, sigPolicyId->xmlChildrenNode, 1); | ||||||
|  |     xmlSecBufferPtr policyContent = xmlSecBufferCreate(1024); | ||||||
|  |     ; | ||||||
|  |     if ( (ctx->policyCtx->contentCallback)(identifier, policyContent) < 0 ) { | ||||||
|  |       xmlXadesInternalError("policyContext callback fails.\n", NULL); | ||||||
|  |       xmlFree(identifier); | ||||||
|  |       return(-1); | ||||||
|  |     } | ||||||
|  |     xmlFree(identifier); | ||||||
|  |  | ||||||
|  |     xmlChar *policyHashValue = xmlXadesSha256DigestValueInBase64(xmlSecBufferGetData(policyContent), | ||||||
|  |                                                                  xmlSecBufferGetSize(policyContent)); | ||||||
|  |  | ||||||
|  |     xmlSecBufferDestroy(policyContent); | ||||||
|  |     xmlXadesTmplAddDigest(sigPolicyHashNode, NULL, policyHashValue); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return xmlSecDSigCtxSign(ctx->dsigCtx, signNode); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlXadesDSigCtxDestroy(xmlXadesDSigCtxPtr ctx) { | ||||||
|  |   if ( ctx == NULL ) { | ||||||
|  |     return(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   free(ctx); | ||||||
|  |   return(0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesXPathFirstElement(xmlDocPtr doc, const xmlChar *xpath) { | ||||||
|  |   xmlXPathContextPtr xpathCtx; | ||||||
|  |   xmlXPathObjectPtr xpathResult; | ||||||
|  |   xmlNodePtr node; | ||||||
|  |  | ||||||
|  |   // obtener QualifyingProteries | ||||||
|  |  | ||||||
|  |   xpathCtx = xmlXPathNewContext(doc); | ||||||
|  |   /* register namespaces */ | ||||||
|  |   // TOMADO DE: xmlsec1/src/xpath.c | ||||||
|  |   for(xmlNsPtr ns = xmlDocGetRootElement(doc)->nsDef; ns != NULL; ns = ns->next) { | ||||||
|  |     /* check that we have no other namespace with same prefix already */ | ||||||
|  |     if((ns->prefix != NULL) && (xmlXPathNsLookup(xpathCtx, ns->prefix) == NULL)){ | ||||||
|  |       int ret = xmlXPathRegisterNs(xpathCtx, ns->prefix, ns->href); | ||||||
|  |       if(ret != 0) { | ||||||
|  |         xmlXadesXmlError2("xmlXPathRegisterNs", NULL, | ||||||
|  |                           "prefix=%s", xmlSecErrorsSafeString(ns->prefix)); | ||||||
|  |         return(NULL); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   xpathResult = xmlXPathEvalExpression(xpath, xpathCtx); | ||||||
|  |   if ( xmlXPathNodeSetIsEmpty( xpathResult->nodesetval ) ) { | ||||||
|  |     xmlXadesInternalError("can't find %s \n", xpath); | ||||||
|  |     xmlXPathFreeObject(xpathResult); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // obtener puntero a nodo | ||||||
|  |   node = xpathResult->nodesetval->nodeTab[0]; | ||||||
|  |   if ( node->type != XML_ELEMENT_NODE ) { | ||||||
|  |     xmlXadesInternalError("expected element\n", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return(node); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static xmlChar * | ||||||
|  | xmlXadesSha256DigestValueInBase64(const unsigned char *message, size_t message_len) | ||||||
|  | { | ||||||
|  |   unsigned char digest[2048]; | ||||||
|  |   unsigned int digest_len; | ||||||
|  |   EVP_MD_CTX *mdctx; | ||||||
|  |  | ||||||
|  |   if((mdctx = EVP_MD_CTX_new()) == NULL) { | ||||||
|  |     xmlXadesInternalError("EVP_MD_CTX_new().\n", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if(1 != EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) { | ||||||
|  |     xmlXadesInternalError("EVP_DigestInit_ex().\n", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if(1 != EVP_DigestUpdate(mdctx, message, message_len)) { | ||||||
|  |     xmlXadesInternalError("EVP_DigestUpdate().\n", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if(1 != EVP_DigestFinal_ex(mdctx, digest, &digest_len)) { | ||||||
|  |     xmlXadesInternalError("EVP_DigestFinal_ex().\n", NULL); | ||||||
|  |     return(NULL); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   EVP_MD_CTX_free(mdctx); | ||||||
|  |   return(xmlSecBase64Encode(digest, digest_len, 0)); | ||||||
|  | } | ||||||
							
								
								
									
										108
									
								
								experimental/facho-signer/src/xades/xades.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								experimental/facho-signer/src/xades/xades.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | |||||||
|  | /** | ||||||
|  |  * This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
|  |  * this repository contains the full copyright notices and license terms. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef XADES_H | ||||||
|  | #define XADES_H | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include <libxml/tree.h> | ||||||
|  |  | ||||||
|  | #define XMLSEC_NO_XSLT 1 | ||||||
|  |  | ||||||
|  | #include <xmlsec/xmltree.h> | ||||||
|  | #include <xmlsec/transforms.h> | ||||||
|  | #include <xmlsec/xmldsig.h> | ||||||
|  | #include <xmlsec/base64.h> | ||||||
|  |  | ||||||
|  | #include "xmlsec1/errors_helpers.h" | ||||||
|  |  | ||||||
|  | #define xmlXadesAssert2(p, ret) \ | ||||||
|  |   xmlSecAssert2(p, ret) | ||||||
|  |  | ||||||
|  | #define xmlXadesNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) \ | ||||||
|  |   xmlSecNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) | ||||||
|  |  | ||||||
|  | #define xmlXadesXmlError2(errorFunction, errorObject, msg, param) \ | ||||||
|  |   xmlSecXmlError2(errorFunction, errorObject, msg, param) | ||||||
|  |  | ||||||
|  | #define xmlXadesErrorsSafeString(msg) \ | ||||||
|  |   xmlSecErrorsSafeString(msg) | ||||||
|  |  | ||||||
|  | #define xmlXadesInternalError(errorFunction, errorObject) \ | ||||||
|  |   xmlSecInternalError(errorFunction, errorObject) | ||||||
|  |  | ||||||
|  | #define xmlXadesNodeAlreadyPresentError(parent, nodeName, errObject) \ | ||||||
|  |   xmlSecNodeAlreadyPresentError(parent, nodeName, errObject) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | typedef int xmlXadesSize; | ||||||
|  | typedef enum _XADES_DIGEST_METHOD{ | ||||||
|  |   XADES_DIGEST_SHA256 | ||||||
|  | } XADES_DIGEST_METHOD; | ||||||
|  |  | ||||||
|  | typedef int(*xmlXadesPolicyIdentifierContentCallback)(const xmlChar *policyId, xmlSecBuffer *); | ||||||
|  |  | ||||||
|  | typedef struct _xmlXadesPolicyIdentifierCtx  xmlXadesPolicyIdentifierCtx, *xmlXadesPolicyIdentifierCtxPtr; | ||||||
|  | struct _xmlXadesPolicyIdentifierCtx { | ||||||
|  |   xmlXadesPolicyIdentifierContentCallback contentCallback; | ||||||
|  | }; | ||||||
|  |    | ||||||
|  | typedef struct _xmlXadesDSigCtx xmlXadesDSigCtx, *xmlXadesDSigCtxPtr; | ||||||
|  | struct _xmlXadesDSigCtx { | ||||||
|  |   xmlSecDSigCtxPtr dsigCtx; | ||||||
|  |   XADES_DIGEST_METHOD digestMethod; | ||||||
|  |   xmlXadesPolicyIdentifierCtxPtr policyCtx; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | xmlXadesDSigCtxPtr | ||||||
|  | xmlXadesDSigCtxCreate(xmlSecDSigCtxPtr dsigCtx, XADES_DIGEST_METHOD digestMethod,  xmlXadesPolicyIdentifierCtxPtr policyCtx); | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlXadesDSigCtxSign(xmlXadesDSigCtxPtr ctx, xmlNodePtr signNode); | ||||||
|  |  | ||||||
|  | int | ||||||
|  | xmlXadesDSigCtxDestroy(xmlXadesDSigCtxPtr ctx); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplQualifyingPropertiesCreate(xmlDocPtr doc, xmlNodePtr signatureNode, const xmlChar *id); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignedProperties(xmlNodePtr qualifyingPropertiesNode, const xmlChar* id); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSigningCertificate(xmlNodePtr parentNode, xmlSecTransformId digestMethodId); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddCert(xmlNodePtr signingCertificateNode); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddCertDigest(xmlNodePtr signingCertificateNode, const xmlChar *digestMethod, const xmlChar *digestValue); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignedSignatureProperties(xmlNodePtr parentNode, struct tm* signingTime); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignaturePolicyIdentifier(xmlNodePtr signedSignaturePropertiesNode); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignaturePolicyId(xmlNodePtr signaturePolicyIdentifierNode); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSigPolicyId(xmlNodePtr signaturePolicyId, const xmlChar* identifier, const xmlChar *description); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSigPolicyHash(xmlNodePtr parentNode, xmlSecTransformId digestMethodId); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddSignerRole(xmlNodePtr signedSignaturePropertiesNode, const xmlChar* role); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddDigest(xmlNodePtr parentNode, const xmlChar *digestMethod, const xmlChar *digestValue); | ||||||
|  |  | ||||||
|  | xmlNodePtr | ||||||
|  | xmlXadesTmplAddIssuerSerial(xmlNodePtr certNode, const xmlChar *issuerName, const xmlChar *issuerNumber); | ||||||
|  |  | ||||||
|  | #endif //XADES_H | ||||||
							
								
								
									
										94
									
								
								experimental/facho-signer/src/xades/xades_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								experimental/facho-signer/src/xades/xades_test.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | /** | ||||||
|  |  * This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
|  |  * this repository contains the full copyright notices and license terms. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <time.h> | ||||||
|  |  | ||||||
|  | #include <libxml/tree.h> | ||||||
|  | #include "minunit.h" | ||||||
|  |  | ||||||
|  | #include "xades.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | MU_TEST(test_xml_add_node_recursive) { | ||||||
|  |   xmlDocPtr doc; | ||||||
|  |   xmlNodePtr root; | ||||||
|  |   xmlNodePtr child; | ||||||
|  |   xmlChar* xmlbuff; | ||||||
|  |   int xmlbuffsize; | ||||||
|  |    | ||||||
|  |   doc = xmlNewDoc(BAD_CAST "1.0"); | ||||||
|  |   root = xmlNewNode(NULL, BAD_CAST "root"); | ||||||
|  |   xmlDocSetRootElement(doc, root); | ||||||
|  |  | ||||||
|  |   child = xmlXadesAddChildRecursiveNs(root, BAD_CAST "A/B/C", NULL); | ||||||
|  |   mu_check(child != NULL); | ||||||
|  |  | ||||||
|  |   xmlDocDumpMemory(doc, &xmlbuff, &xmlbuffsize); | ||||||
|  |   mu_assert_string_eq("<?xml version=\"1.0\"?>\n" | ||||||
|  |                       "<root>\n" | ||||||
|  |                       "<A>\n" | ||||||
|  |                       "<B>\n" | ||||||
|  |                       "<C/>\n" | ||||||
|  |                       "</B>\n" | ||||||
|  |                       "</A>\n" | ||||||
|  |                       "</root>\n" | ||||||
|  |                       , (char *)xmlbuff); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | MU_TEST(test_qualifying_properties_layout) { | ||||||
|  |   xmlDocPtr doc; | ||||||
|  |   xmlNodePtr root; | ||||||
|  |   xmlNodePtr node; | ||||||
|  |   xmlChar* xmlbuff; | ||||||
|  |   int buffersize; | ||||||
|  |   struct tm tm; | ||||||
|  |  | ||||||
|  |   memset(&tm, 0, sizeof(tm)); | ||||||
|  |   tm.tm_year = 2021 - 1900; | ||||||
|  |   tm.tm_mon = 11; | ||||||
|  |   tm.tm_mday = 6; | ||||||
|  |   tm.tm_hour = 12; | ||||||
|  |   tm.tm_min = 0; | ||||||
|  |   tm.tm_sec = 50; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   doc = xmlNewDoc(BAD_CAST "1.0"); | ||||||
|  |   root = xmlNewNode(NULL, BAD_CAST "root"); | ||||||
|  |   xmlDocSetRootElement(doc, root); | ||||||
|  |    | ||||||
|  |   node = xmlXadesTmplQualifyingPropertiesCreateNsPref(doc, BAD_CAST "123", NULL); | ||||||
|  |   xmlXadesTmplAddSignedSignatureProperties(node, &tm); | ||||||
|  |   mu_check(node != NULL); | ||||||
|  |    | ||||||
|  |   xmlSecAddChildNode(root, node); | ||||||
|  |   xmlDocDumpMemory(doc, &xmlbuff, &buffersize); | ||||||
|  |  | ||||||
|  |   // bit4bit: no se como pasar el namespace al root | ||||||
|  |   mu_assert_string_eq("<?xml version=\"1.0\"?>\n" | ||||||
|  |                       "<root>\n" | ||||||
|  |                       "<QualifyingProperties xmlns=\"http://uri.etsi.org/01903/v1.3.2#\" id=\"123\">\n" | ||||||
|  |                       "<SignedProperties>\n" | ||||||
|  |                       "<SignedSignatureProperties>\n" | ||||||
|  |                       "<SigningTime>2021-12-06T12:00:50</SigningTime>\n" | ||||||
|  |                       "</SignedSignatureProperties>\n" | ||||||
|  |                       "</SignedProperties>\n" | ||||||
|  |                       "</QualifyingProperties>\n" | ||||||
|  |                       "</root>\n" | ||||||
|  |                       , (char *)xmlbuff); | ||||||
|  |    | ||||||
|  |   xmlFree(xmlbuff); | ||||||
|  |   xmlFreeDoc(doc); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | MU_TEST_SUITE(test_suite) { | ||||||
|  |   MU_RUN_TEST(test_xml_add_node_recursive); | ||||||
|  |   MU_RUN_TEST(test_qualifying_properties_layout); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main() { | ||||||
|  |   MU_RUN_SUITE(test_suite); | ||||||
|  |   MU_REPORT(); | ||||||
|  |   return MU_EXIT_CODE; | ||||||
|  | } | ||||||
							
								
								
									
										260
									
								
								experimental/facho-signer/src/xades/xmlsec1/errors.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								experimental/facho-signer/src/xades/xmlsec1/errors.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,260 @@ | |||||||
|  | /* | ||||||
|  |  * XML Security Library (http://www.aleksey.com/xmlsec). | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * This is free software; see Copyright file in the source | ||||||
|  |  * distribution for preciese wording. | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. | ||||||
|  |  */ | ||||||
|  | /** | ||||||
|  |  * SECTION:errors | ||||||
|  |  * @Short_description: Error reporting and logging functions. | ||||||
|  |  * @Stability: Stable | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #define XMLSEC_PRIVATE 1 | ||||||
|  | #define XMLSEC_NO_XSLT 1 | ||||||
|  |  | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <time.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include <libxml/tree.h> | ||||||
|  |  | ||||||
|  | #include <xmlsec/xmlsec.h> | ||||||
|  | #include <xmlsec/xmltree.h> | ||||||
|  | #include <xmlsec/private.h> | ||||||
|  | #include <xmlsec/errors.h> | ||||||
|  |  | ||||||
|  | /* Must be bigger than fatal_error */ | ||||||
|  | #define XMLSEC_ERRORS_BUFFER_SIZE       1024 | ||||||
|  |  | ||||||
|  | /* Must fit into xmlChar[XMLSEC_ERRORS_BUFFER_SIZE] */ | ||||||
|  | static const xmlChar fatal_error[] = "Can not format error message"; | ||||||
|  |  | ||||||
|  | typedef struct _xmlSecErrorDescription                  xmlSecErrorDescription, *xmlSecErrorDescriptionPtr; | ||||||
|  | struct _xmlSecErrorDescription { | ||||||
|  |     int                 errorCode; | ||||||
|  |     const char*         errorMsg; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static xmlSecErrorDescription xmlSecErrorsTable[XMLSEC_ERRORS_MAX_NUMBER + 1] = { | ||||||
|  |   { XMLSEC_ERRORS_R_XMLSEC_FAILED,              "xmlsec library function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MALLOC_FAILED,              "malloc function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_STRDUP_FAILED,              "strdup function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CRYPTO_FAILED,              "crypto library function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_XML_FAILED,                 "libxml2 library function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_XSLT_FAILED,                "libxslt library function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_IO_FAILED,                  "io function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_DISABLED,                   "feature is disabled" }, | ||||||
|  |   { XMLSEC_ERRORS_R_NOT_IMPLEMENTED,            "feature is not implemented" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_CONFIG,             "invalid configuration" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_SIZE,               "invalid size" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_DATA,               "invalid data" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_RESULT,             "invalid result" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_TYPE,               "invalid type" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_OPERATION,          "invalid operation" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_STATUS,             "invalid status" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_FORMAT,             "invalid format" }, | ||||||
|  |   { XMLSEC_ERRORS_R_DATA_NOT_MATCH,             "data do not match" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_VERSION,            "invalid version" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_NODE,               "invalid node" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,       "invalid node content" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,     "invalid node attribute" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MISSING_NODE_ATTRIBUTE,     "missing node attribute" }, | ||||||
|  |   { XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,       "node already present" }, | ||||||
|  |   { XMLSEC_ERRORS_R_UNEXPECTED_NODE,            "unexpected node" }, | ||||||
|  |   { XMLSEC_ERRORS_R_NODE_NOT_FOUND,             "node node found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_TRANSFORM,          "invalid transform" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_TRANSFORM_KEY,      "invalid transform key" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_URI_TYPE,           "invalid URI type" }, | ||||||
|  |   { XMLSEC_ERRORS_R_TRANSFORM_SAME_DOCUMENT_REQUIRED,   "same document is required for transform" }, | ||||||
|  |   { XMLSEC_ERRORS_R_TRANSFORM_DISABLED,         "transform is disabled" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_KEY_DATA,           "invalid key data" }, | ||||||
|  |   { XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND,         "key data is not found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,     "key data already exist" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,      "invalid key data size" }, | ||||||
|  |   { XMLSEC_ERRORS_R_KEY_NOT_FOUND,              "key is not found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_KEYDATA_DISABLED,           "key data is disabled" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MAX_RETRIEVALS_LEVEL,       "maximum key retrieval level" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MAX_RETRIEVAL_TYPE_MISMATCH,"key retrieval type mismatch" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MAX_ENCKEY_LEVEL,           "maximum encrypted key level" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,         "certificate verification failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_NOT_FOUND,             "certificate is not found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_REVOKED,               "certificate is revoked" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_ISSUER_FAILED,         "certificate issuer check failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,         "certificate is not yet valid" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,           "certificate has expired" }, | ||||||
|  |   { XMLSEC_ERRORS_R_DSIG_NO_REFERENCES,         "Reference nodes are not found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_DSIG_INVALID_REFERENCE,     "Reference verification failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_ASSERTION,                  "assertion" }, | ||||||
|  |   { 0,                                          NULL} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static xmlSecErrorsCallback xmlSecErrorsClbk = xmlSecErrorsDefaultCallback; | ||||||
|  | static int  xmlSecPrintErrorMessages = 1;       /* whether the error messages will be printed immediately */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsInit: | ||||||
|  |  * | ||||||
|  |  * Initializes the errors reporting. It is called from #xmlSecInit function. | ||||||
|  |  * and applications must not call this function directly. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsInit(void) { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsShutdown: | ||||||
|  |  * | ||||||
|  |  * Cleanups the errors reporting. It is called from #xmlSecShutdown function. | ||||||
|  |  * and applications must not call this function directly. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsShutdown(void) { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsSetCallback: | ||||||
|  |  * @callback:           the new errors callback function. | ||||||
|  |  * | ||||||
|  |  * Sets the errors callback function to @callback that will be called | ||||||
|  |  * every time an error occurs. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsSetCallback(xmlSecErrorsCallback callback) { | ||||||
|  |     xmlSecErrorsClbk = callback; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsDefaultCallback: | ||||||
|  |  * @file:               the error location file name (__FILE__ macro). | ||||||
|  |  * @line:               the error location line number (__LINE__ macro). | ||||||
|  |  * @func:               the error location function name (__FUNCTION__ macro). | ||||||
|  |  * @errorObject:        the error specific error object | ||||||
|  |  * @errorSubject:       the error specific error subject. | ||||||
|  |  * @reason:             the error code. | ||||||
|  |  * @msg:                the additional error message. | ||||||
|  |  * | ||||||
|  |  * The default error reporting callback that utilizes LibXML | ||||||
|  |  * error reporting #xmlGenericError function. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsDefaultCallback(const char* file, int line, const char* func, | ||||||
|  |                             const char* errorObject, const char* errorSubject, | ||||||
|  |                             int reason, const char* msg) { | ||||||
|  |     if(xmlSecPrintErrorMessages) { | ||||||
|  |         const char* error_msg = NULL; | ||||||
|  |         xmlSecSize i; | ||||||
|  |  | ||||||
|  |         for(i = 0; (i < XMLSEC_ERRORS_MAX_NUMBER) && (xmlSecErrorsGetMsg(i) != NULL); ++i) { | ||||||
|  |             if(xmlSecErrorsGetCode(i) == reason) { | ||||||
|  |                 error_msg = xmlSecErrorsGetMsg(i); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         xmlGenericError(xmlGenericErrorContext, | ||||||
|  |             "func=%s:file=%s:line=%d:obj=%s:subj=%s:error=%d:%s:%s\n", | ||||||
|  |             (func != NULL) ? func : "unknown", | ||||||
|  |             (file != NULL) ? file : "unknown", | ||||||
|  |             line, | ||||||
|  |             (errorObject != NULL) ? errorObject : "unknown", | ||||||
|  |             (errorSubject != NULL) ? errorSubject : "unknown", | ||||||
|  |             reason, | ||||||
|  |             (error_msg != NULL) ? error_msg : "", | ||||||
|  |             (msg != NULL) ? msg : ""); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsDefaultCallbackEnableOutput: | ||||||
|  |  * @enabled:            the flag. | ||||||
|  |  * | ||||||
|  |  * Enables or disables calling LibXML2 callback from the default | ||||||
|  |  * errors callback. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsDefaultCallbackEnableOutput(int enabled) { | ||||||
|  |     xmlSecPrintErrorMessages = enabled; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsGetCode: | ||||||
|  |  * @pos:                the error position. | ||||||
|  |  * | ||||||
|  |  * Gets the known error code at position @pos. | ||||||
|  |  * | ||||||
|  |  * Returns: the known error code or 0 if @pos is greater than | ||||||
|  |  * total number of known error codes. | ||||||
|  |  */ | ||||||
|  | int | ||||||
|  | xmlSecErrorsGetCode(xmlSecSize pos) { | ||||||
|  |     /* could not use asserts here! */ | ||||||
|  |     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { | ||||||
|  |         return(xmlSecErrorsTable[pos].errorCode); | ||||||
|  |     } | ||||||
|  |     return(0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsGetMsg: | ||||||
|  |  * @pos:                the error position. | ||||||
|  |  * | ||||||
|  |  * Gets the known error message at position @pos. | ||||||
|  |  * | ||||||
|  |  * Returns: the known error message or NULL if @pos is greater than | ||||||
|  |  * total number of known error codes. | ||||||
|  |  */ | ||||||
|  | const char* | ||||||
|  | xmlSecErrorsGetMsg(xmlSecSize pos) { | ||||||
|  |     /* could not use asserts here! */ | ||||||
|  |     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { | ||||||
|  |         return(xmlSecErrorsTable[pos].errorMsg); | ||||||
|  |     } | ||||||
|  |     return(NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecError: | ||||||
|  |  * @file:               the error location filename (__FILE__). | ||||||
|  |  * @line:               the error location line number (__LINE__). | ||||||
|  |  * @func:               the error location function (__FUNCTION__). | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @errorSubject:       the error specific error subject (e.g. failed function name). | ||||||
|  |  * @reason:             the error code. | ||||||
|  |  * @msg:                the error message in printf format. | ||||||
|  |  * @...:                the parameters for the @msg. | ||||||
|  |  * | ||||||
|  |  * Reports an error to the default (#xmlSecErrorsDefaultCallback) or | ||||||
|  |  * application specific callback installed using #xmlSecErrorsSetCallback | ||||||
|  |  * function. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecError(const char* file, int line, const char* func, | ||||||
|  |             const char* errorObject, const char* errorSubject, | ||||||
|  |             int reason, const char* msg, ...) { | ||||||
|  |     if(xmlSecErrorsClbk != NULL) { | ||||||
|  |         xmlChar error_msg[XMLSEC_ERRORS_BUFFER_SIZE]; | ||||||
|  |         int ret; | ||||||
|  |  | ||||||
|  |         if(msg != NULL) { | ||||||
|  |             va_list va; | ||||||
|  |  | ||||||
|  |             va_start(va, msg); | ||||||
|  |             ret = xmlStrVPrintf(error_msg, sizeof(error_msg), msg, va); | ||||||
|  |             if(ret < 0) { | ||||||
|  |                 /* Can't really report an error from an error callback */ | ||||||
|  |                 memcpy(error_msg, fatal_error, sizeof(fatal_error)); | ||||||
|  |             } | ||||||
|  |             error_msg[sizeof(error_msg) - 1] = '\0'; /* just in case */ | ||||||
|  |             va_end(va); | ||||||
|  |         } else { | ||||||
|  |             error_msg[0] = '\0'; | ||||||
|  |         } | ||||||
|  |         xmlSecErrorsClbk(file, line, func, errorObject, errorSubject, reason, (char*)error_msg); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										869
									
								
								experimental/facho-signer/src/xades/xmlsec1/errors_helpers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										869
									
								
								experimental/facho-signer/src/xades/xmlsec1/errors_helpers.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,869 @@ | |||||||
|  | /* | ||||||
|  |  * XML Security Library (http://www.aleksey.com/xmlsec). | ||||||
|  |  * | ||||||
|  |  * Internal header only used during the compilation, | ||||||
|  |  * | ||||||
|  |  * This is free software; see Copyright file in the source | ||||||
|  |  * distribution for preciese wording. | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef __XMLSEC_ERROR_HELPERS_H__ | ||||||
|  | #define __XMLSEC_ERROR_HELPERS_H__ | ||||||
|  |  | ||||||
|  | #include <errno.h> | ||||||
|  | #include <xmlsec/errors.h> | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif /* __cplusplus */ | ||||||
|  |  | ||||||
|  | /********************************************************************** | ||||||
|  |  * | ||||||
|  |  * Error handling macros. | ||||||
|  |  * | ||||||
|  |  **********************************************************************/ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInternalError: | ||||||
|  |  * @errorFunction:      the failed function name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting internal XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInternalError(errorFunction, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     (errorFunction),                        \ | ||||||
|  |                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ | ||||||
|  |                     XMLSEC_ERRORS_NO_MESSAGE                \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInternalError2: | ||||||
|  |  * @errorFunction:      the failed function name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting internal XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInternalError2(errorFunction, errorObject, msg, param) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     (errorFunction),                        \ | ||||||
|  |                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ | ||||||
|  |                     (msg), (param)                          \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInternalError3: | ||||||
|  |  * @errorFunction:      the failed function name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param1. | ||||||
|  |  * @param2:             the extra message param2. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting internal XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInternalError3(errorFunction, errorObject, msg, param1, param2) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     (errorFunction),                        \ | ||||||
|  |                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ | ||||||
|  |                     (msg), (param1), (param2)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInternalError4: | ||||||
|  |  * @errorFunction:      the failed function name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param1. | ||||||
|  |  * @param2:             the extra message param2. | ||||||
|  |  * @param3:             the extra message param3. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting internal XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInternalError4(errorFunction, errorObject, msg, param1, param2, param3) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     (errorFunction),                        \ | ||||||
|  |                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ | ||||||
|  |                     (msg), (param1), (param2), (param3)     \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecMallocError: | ||||||
|  |  * @allocSize:          the failed allocation size. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting xmlMalloc() errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecMallocError(allocSize, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     "xmlMalloc",                            \ | ||||||
|  |                     XMLSEC_ERRORS_R_MALLOC_FAILED,          \ | ||||||
|  |                     "size=%lu", (unsigned long)(allocSize)  \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecStrdupError: | ||||||
|  |  * @str:                the failed string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting xmlStrdup() errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecStrdupError(str, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     "xmlStrdup",                            \ | ||||||
|  |                     XMLSEC_ERRORS_R_STRDUP_FAILED,          \ | ||||||
|  |                     "size=%lu", (unsigned long)xmlStrlen(str) \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXmlError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting generic XML errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXmlError(errorFunction, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlGetLastError();        \ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XML_FAILED,        \ | ||||||
|  |                    "xml error: %lu: %s",              \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXmlError2: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting generic XML errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXmlError2(errorFunction, errorObject, msg, param) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlGetLastError();        \ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XML_FAILED,        \ | ||||||
|  |                    msg "; xml error: %lu: %s",        \ | ||||||
|  |                    (param),                           \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXmlParserError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @ctxt:               the parser context. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting XML parser errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXmlParserError(errorFunction, ctxt, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlCtxtGetLastError(ctxt);\ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XML_FAILED,        \ | ||||||
|  |                    "xml error: %lu: %s",              \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXmlParserError2: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @ctxt:               the parser context. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting XML parser errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXmlParserError2(errorFunction, ctxt, errorObject, msg, param) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlCtxtGetLastError(ctxt);\ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XML_FAILED,        \ | ||||||
|  |                    msg "; xml error: %lu: %s",        \ | ||||||
|  |                    (param),                           \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXsltError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @ctxt:               the parser context. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting XSLT errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXsltError(errorFunction, ctxt, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlGetLastError();        \ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XSLT_FAILED,       \ | ||||||
|  |                    "xslt error: %lu: %s",             \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecIOError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @name:               the filename, function name, uri, etc. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting IO errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecIOError(errorFunction, name, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_IO_FAILED,         \ | ||||||
|  |                    "name=\"%s\"; errno=%d",           \ | ||||||
|  |                    xmlSecErrorsSafeString(name),      \ | ||||||
|  |                    errno                              \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecNotImplementedError: | ||||||
|  |  * @details:           the additional details. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "not implemented" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecNotImplementedError(details) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ | ||||||
|  |                     "details=%s",                           \ | ||||||
|  |                     xmlSecErrorsSafeString(details)         \ | ||||||
|  |         ) | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @expected:           the expected value. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect exact match. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ | ||||||
|  |                     "invalid size for '%s': actual=%lu is not equal to expected=%lu", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(expected)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeLessThanError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @expected:           the expected value. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect at least the expected size. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeLessThanError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ | ||||||
|  |                     "invalid size for '%s': actual=%lu is less than expected=%lu", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(expected)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeMoreThanError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @expected:           the expected value. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect at most the expected size. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeMoreThanError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ | ||||||
|  |                     "invalid size for '%s': actual=%lu is more than expected=%lu", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(expected)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeNotMultipleOfError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @divider:            the expected divider. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect the size to be a multiple of the divider. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeNotMultipleOfError(name, actual, divider, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ | ||||||
|  |                     "invalid size for '%s': actual=%lu is not a multiple of %lu", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(divider)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeOtherError: | ||||||
|  |  * @msg:                the message about the error. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect exact match. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeOtherError(msg, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ | ||||||
|  |                     "invalid size: %s",                     \ | ||||||
|  |                     xmlSecErrorsSafeString(msg)             \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidDataError: | ||||||
|  |  * @msg:                the msg with explanation. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid data" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidDataError(msg, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_DATA,           \ | ||||||
|  |                     "%s",                                   \ | ||||||
|  |                     xmlSecErrorsSafeString(msg)             \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidStringDataError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value as a string. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid data" errors for string. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidStringDataError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_DATA,           \ | ||||||
|  |                     "invalid data for '%s': actual='%s' and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     xmlSecErrorsSafeString(actual),         \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidIntegerDataError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value as an integer. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid data" errors for integers. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidIntegerDataError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_DATA,           \ | ||||||
|  |                     "invalid data for '%s': actual=%ld and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidIntegerDataError2: | ||||||
|  |  * @name1:              the name of the first variable, parameter, etc. | ||||||
|  |  * @actual1:            the actual first value as an integer. | ||||||
|  |  * @name2:              the name of the second variable, parameter, etc. | ||||||
|  |  * @actual2:            the actual second value as an integer. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid data" errors for integers. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidIntegerDataError2(name1, actual1, name2, actual2, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_DATA,           \ | ||||||
|  |                     "invalid data: actual value '%s'=%ld, actual value '%s'=%ld and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name1),          \ | ||||||
|  |                     (unsigned long)(actual1),               \ | ||||||
|  |                     xmlSecErrorsSafeString(name2),          \ | ||||||
|  |                     (unsigned long)(actual2),               \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTypeError: | ||||||
|  |  * @msg:                the msg with explanation. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid type" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTypeError(msg, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ | ||||||
|  |                     "%s",                                   \ | ||||||
|  |                     xmlSecErrorsSafeString(msg)             \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidStringTypeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value as a string. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid type" errors for string. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidStringTypeError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ | ||||||
|  |                     "invalid type for '%s': actual='%s' and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     xmlSecErrorsSafeString(actual),         \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidIntegerTypeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value as an integer. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid type" errors for integers. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidIntegerTypeError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ | ||||||
|  |                     "invalid type for '%s': actual=%ld and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidIntegerTypeError2: | ||||||
|  |  * @name1:              the name of the first variable, parameter, etc. | ||||||
|  |  * @actual1:            the actual first value as an integer. | ||||||
|  |  * @name2:              the name of the second variable, parameter, etc. | ||||||
|  |  * @actual2:            the actual second value as an integer. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid type" errors for integers. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidIntegerTypeError2(name1, actual1, name2, actual2, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ | ||||||
|  |                     "invalid type: actual value '%s'=%ld, actual value '%s'=%ld and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name1),          \ | ||||||
|  |                     (unsigned long)(actual1),               \ | ||||||
|  |                     xmlSecErrorsSafeString(name2),          \ | ||||||
|  |                     (unsigned long)(actual2),               \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidNodeError: | ||||||
|  |  * @actualNode:         the actual node. | ||||||
|  |  * @expectedNodeName:   the expected node name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid node errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidNodeError(actualNode, expectedNodeName, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* actualNodeName = xmlSecNodeGetName(actualNode); \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_NODE,      \ | ||||||
|  |                    "actual=%s; expected=%s",          \ | ||||||
|  |                    xmlSecErrorsSafeString(actualNodeName),  \ | ||||||
|  |                    xmlSecErrorsSafeString(expectedNodeName) \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidNodeContentError: | ||||||
|  |  * @node:               the node. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @reason:             the reason why node content is invalid. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid node content errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidNodeContentError(node, errorObject, reason) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* nName = xmlSecNodeGetName(node);  \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, \ | ||||||
|  |                    "node=%s; reason=%s",              \ | ||||||
|  |                    xmlSecErrorsSafeString(nName),     \ | ||||||
|  |                    xmlSecErrorsSafeString(reason)     \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidNodeAttributeError: | ||||||
|  |  * @node:               the node. | ||||||
|  |  * @attrName:           the attribute name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @reason:             the reason why node content is invalid. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid node attribute errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidNodeAttributeError(node, attrName, errorObject, reason) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* nName = xmlSecNodeGetName(node);  \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE, \ | ||||||
|  |                    "node=%s; attribute=%s; reason=%s",\ | ||||||
|  |                    xmlSecErrorsSafeString(nName),     \ | ||||||
|  |                    xmlSecErrorsSafeString(attrName),  \ | ||||||
|  |                    xmlSecErrorsSafeString(reason)     \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecNodeAlreadyPresentError: | ||||||
|  |  * @parent:             the parent node. | ||||||
|  |  * @nodeName:           the node name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting node already present errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecNodeAlreadyPresentError(parent, nodeName, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* pName = xmlSecNodeGetName(parent);\ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT, \ | ||||||
|  |                    "parent=%s; node=%s",              \ | ||||||
|  |                    xmlSecErrorsSafeString(pName),     \ | ||||||
|  |                    xmlSecErrorsSafeString(nodeName)   \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecUnexpectedNodeError: | ||||||
|  |  * @node:               the node. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid node errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecUnexpectedNodeError(node, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* nName = xmlSecNodeGetName(node);  \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_UNEXPECTED_NODE,   \ | ||||||
|  |                    "node=%s",                         \ | ||||||
|  |                    xmlSecErrorsSafeString(nName)      \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecNodeNotFoundError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @startNode:          the search start node. | ||||||
|  |  * @targetNodeName:     the expected child node name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting node not found errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* startNodeName = xmlSecNodeGetName(startNode); \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_NODE_NOT_FOUND,    \ | ||||||
|  |                    "startNode=%s; target=%s",         \ | ||||||
|  |                    xmlSecErrorsSafeString(startNodeName), \ | ||||||
|  |                    xmlSecErrorsSafeString(targetNodeName) \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTransfromError: | ||||||
|  |  * @transform:          the transform. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid transform errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTransfromError(transform) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)xmlSecTransformGetName(transform), \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_TRANSFORM, \ | ||||||
|  |                    XMLSEC_ERRORS_NO_MESSAGE           \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTransfromError2: | ||||||
|  |  * @transform:          the transform. | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid transform errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTransfromError2(transform, msg, param) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)xmlSecTransformGetName(transform), \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_TRANSFORM, \ | ||||||
|  |                    (msg), (param)                     \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTransfromStatusError: | ||||||
|  |  * @transform:          the transform. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid transform status errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTransfromStatusError(transform) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)xmlSecTransformGetName(transform), \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_STATUS,    \ | ||||||
|  |                    "transformStatus=%d",              \ | ||||||
|  |                    (int)((transform)->status)         \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTransfromStatusError2: | ||||||
|  |  * @transform:          the transform. | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid transform status errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTransfromStatusError2(transform, msg) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)xmlSecTransformGetName(transform), \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_STATUS,    \ | ||||||
|  |                    "transformStatus=%ld, msg=%s",     \ | ||||||
|  |                    (long int)((transform)->status),   \ | ||||||
|  |                    msg                                \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidKeyDataSizeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @expected:           the expected value(s). | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid keydata size" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidKeyDataSizeError(actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,  \ | ||||||
|  |                     "invalid key data size: actual=%ld and expected=%ld", \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(expected)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidZeroKeyDataSizeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid keydata size" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidZeroKeyDataSizeError(errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,  \ | ||||||
|  |                     "invalid zero key data size"            \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @details:            the error message. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError(code, errorObject, details) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     "details=%s",                           \ | ||||||
|  |                     xmlSecErrorsSafeString(details)         \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError2: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError2(code, errorObject, msg, param) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     (msg), (param)                          \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError3: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param. | ||||||
|  |  * @param2:             the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError3(code, errorObject, msg, param1, param2) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     (msg), (param1), (param2)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError4: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param. | ||||||
|  |  * @param2:             the extra message param. | ||||||
|  |  * @param3:             the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError4(code, errorObject, msg, param1, param2, param3) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     (msg), (param1), (param2), (param3)     \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError5: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param. | ||||||
|  |  * @param2:             the extra message param. | ||||||
|  |  * @param3:             the extra message param. | ||||||
|  |  * @param4:             the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError5(code, errorObject, msg, param1, param2, param3, param4) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     (msg), (param1), (param2), (param3), (param4) \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif /* __cplusplus */ | ||||||
|  |  | ||||||
|  | #endif /* __XMLSEC_ERROR_HELPERS_H__ */ | ||||||
							
								
								
									
										1952
									
								
								experimental/facho-signer/src/xades/xmlsec1/xmltree.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1952
									
								
								experimental/facho-signer/src/xades/xmlsec1/xmltree.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										259
									
								
								experimental/facho-signer/src/xmlsec1/errors.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								experimental/facho-signer/src/xmlsec1/errors.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,259 @@ | |||||||
|  | /* | ||||||
|  |  * XML Security Library (http://www.aleksey.com/xmlsec). | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * This is free software; see Copyright file in the source | ||||||
|  |  * distribution for preciese wording. | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. | ||||||
|  |  */ | ||||||
|  | /** | ||||||
|  |  * SECTION:errors | ||||||
|  |  * @Short_description: Error reporting and logging functions. | ||||||
|  |  * @Stability: Stable | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #define XMLSEC_PRIVATE 1 | ||||||
|  |  | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <time.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include <libxml/tree.h> | ||||||
|  |  | ||||||
|  | #include <xmlsec/xmlsec.h> | ||||||
|  | #include <xmlsec/xmltree.h> | ||||||
|  | #include <xmlsec/private.h> | ||||||
|  | #include <xmlsec/errors.h> | ||||||
|  |  | ||||||
|  | /* Must be bigger than fatal_error */ | ||||||
|  | #define XMLSEC_ERRORS_BUFFER_SIZE       1024 | ||||||
|  |  | ||||||
|  | /* Must fit into xmlChar[XMLSEC_ERRORS_BUFFER_SIZE] */ | ||||||
|  | static const xmlChar fatal_error[] = "Can not format error message"; | ||||||
|  |  | ||||||
|  | typedef struct _xmlSecErrorDescription                  xmlSecErrorDescription, *xmlSecErrorDescriptionPtr; | ||||||
|  | struct _xmlSecErrorDescription { | ||||||
|  |     int                 errorCode; | ||||||
|  |     const char*         errorMsg; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static xmlSecErrorDescription xmlSecErrorsTable[XMLSEC_ERRORS_MAX_NUMBER + 1] = { | ||||||
|  |   { XMLSEC_ERRORS_R_XMLSEC_FAILED,              "xmlsec library function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MALLOC_FAILED,              "malloc function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_STRDUP_FAILED,              "strdup function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CRYPTO_FAILED,              "crypto library function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_XML_FAILED,                 "libxml2 library function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_XSLT_FAILED,                "libxslt library function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_IO_FAILED,                  "io function failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_DISABLED,                   "feature is disabled" }, | ||||||
|  |   { XMLSEC_ERRORS_R_NOT_IMPLEMENTED,            "feature is not implemented" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_CONFIG,             "invalid configuration" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_SIZE,               "invalid size" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_DATA,               "invalid data" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_RESULT,             "invalid result" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_TYPE,               "invalid type" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_OPERATION,          "invalid operation" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_STATUS,             "invalid status" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_FORMAT,             "invalid format" }, | ||||||
|  |   { XMLSEC_ERRORS_R_DATA_NOT_MATCH,             "data do not match" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_VERSION,            "invalid version" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_NODE,               "invalid node" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,       "invalid node content" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,     "invalid node attribute" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MISSING_NODE_ATTRIBUTE,     "missing node attribute" }, | ||||||
|  |   { XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,       "node already present" }, | ||||||
|  |   { XMLSEC_ERRORS_R_UNEXPECTED_NODE,            "unexpected node" }, | ||||||
|  |   { XMLSEC_ERRORS_R_NODE_NOT_FOUND,             "node node found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_TRANSFORM,          "invalid transform" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_TRANSFORM_KEY,      "invalid transform key" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_URI_TYPE,           "invalid URI type" }, | ||||||
|  |   { XMLSEC_ERRORS_R_TRANSFORM_SAME_DOCUMENT_REQUIRED,   "same document is required for transform" }, | ||||||
|  |   { XMLSEC_ERRORS_R_TRANSFORM_DISABLED,         "transform is disabled" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_KEY_DATA,           "invalid key data" }, | ||||||
|  |   { XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND,         "key data is not found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_KEY_DATA_ALREADY_EXIST,     "key data already exist" }, | ||||||
|  |   { XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,      "invalid key data size" }, | ||||||
|  |   { XMLSEC_ERRORS_R_KEY_NOT_FOUND,              "key is not found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_KEYDATA_DISABLED,           "key data is disabled" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MAX_RETRIEVALS_LEVEL,       "maximum key retrieval level" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MAX_RETRIEVAL_TYPE_MISMATCH,"key retrieval type mismatch" }, | ||||||
|  |   { XMLSEC_ERRORS_R_MAX_ENCKEY_LEVEL,           "maximum encrypted key level" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,         "certificate verification failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_NOT_FOUND,             "certificate is not found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_REVOKED,               "certificate is revoked" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_ISSUER_FAILED,         "certificate issuer check failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,         "certificate is not yet valid" }, | ||||||
|  |   { XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,           "certificate has expired" }, | ||||||
|  |   { XMLSEC_ERRORS_R_DSIG_NO_REFERENCES,         "Reference nodes are not found" }, | ||||||
|  |   { XMLSEC_ERRORS_R_DSIG_INVALID_REFERENCE,     "Reference verification failed" }, | ||||||
|  |   { XMLSEC_ERRORS_R_ASSERTION,                  "assertion" }, | ||||||
|  |   { 0,                                          NULL} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static xmlSecErrorsCallback xmlSecErrorsClbk = xmlSecErrorsDefaultCallback; | ||||||
|  | static int  xmlSecPrintErrorMessages = 1;       /* whether the error messages will be printed immediately */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsInit: | ||||||
|  |  * | ||||||
|  |  * Initializes the errors reporting. It is called from #xmlSecInit function. | ||||||
|  |  * and applications must not call this function directly. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsInit(void) { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsShutdown: | ||||||
|  |  * | ||||||
|  |  * Cleanups the errors reporting. It is called from #xmlSecShutdown function. | ||||||
|  |  * and applications must not call this function directly. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsShutdown(void) { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsSetCallback: | ||||||
|  |  * @callback:           the new errors callback function. | ||||||
|  |  * | ||||||
|  |  * Sets the errors callback function to @callback that will be called | ||||||
|  |  * every time an error occurs. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsSetCallback(xmlSecErrorsCallback callback) { | ||||||
|  |     xmlSecErrorsClbk = callback; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsDefaultCallback: | ||||||
|  |  * @file:               the error location file name (__FILE__ macro). | ||||||
|  |  * @line:               the error location line number (__LINE__ macro). | ||||||
|  |  * @func:               the error location function name (__FUNCTION__ macro). | ||||||
|  |  * @errorObject:        the error specific error object | ||||||
|  |  * @errorSubject:       the error specific error subject. | ||||||
|  |  * @reason:             the error code. | ||||||
|  |  * @msg:                the additional error message. | ||||||
|  |  * | ||||||
|  |  * The default error reporting callback that utilizes LibXML | ||||||
|  |  * error reporting #xmlGenericError function. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsDefaultCallback(const char* file, int line, const char* func, | ||||||
|  |                             const char* errorObject, const char* errorSubject, | ||||||
|  |                             int reason, const char* msg) { | ||||||
|  |     if(xmlSecPrintErrorMessages) { | ||||||
|  |         const char* error_msg = NULL; | ||||||
|  |         xmlSecSize i; | ||||||
|  |  | ||||||
|  |         for(i = 0; (i < XMLSEC_ERRORS_MAX_NUMBER) && (xmlSecErrorsGetMsg(i) != NULL); ++i) { | ||||||
|  |             if(xmlSecErrorsGetCode(i) == reason) { | ||||||
|  |                 error_msg = xmlSecErrorsGetMsg(i); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         xmlGenericError(xmlGenericErrorContext, | ||||||
|  |             "func=%s:file=%s:line=%d:obj=%s:subj=%s:error=%d:%s:%s\n", | ||||||
|  |             (func != NULL) ? func : "unknown", | ||||||
|  |             (file != NULL) ? file : "unknown", | ||||||
|  |             line, | ||||||
|  |             (errorObject != NULL) ? errorObject : "unknown", | ||||||
|  |             (errorSubject != NULL) ? errorSubject : "unknown", | ||||||
|  |             reason, | ||||||
|  |             (error_msg != NULL) ? error_msg : "", | ||||||
|  |             (msg != NULL) ? msg : ""); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsDefaultCallbackEnableOutput: | ||||||
|  |  * @enabled:            the flag. | ||||||
|  |  * | ||||||
|  |  * Enables or disables calling LibXML2 callback from the default | ||||||
|  |  * errors callback. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecErrorsDefaultCallbackEnableOutput(int enabled) { | ||||||
|  |     xmlSecPrintErrorMessages = enabled; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsGetCode: | ||||||
|  |  * @pos:                the error position. | ||||||
|  |  * | ||||||
|  |  * Gets the known error code at position @pos. | ||||||
|  |  * | ||||||
|  |  * Returns: the known error code or 0 if @pos is greater than | ||||||
|  |  * total number of known error codes. | ||||||
|  |  */ | ||||||
|  | int | ||||||
|  | xmlSecErrorsGetCode(xmlSecSize pos) { | ||||||
|  |     /* could not use asserts here! */ | ||||||
|  |     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { | ||||||
|  |         return(xmlSecErrorsTable[pos].errorCode); | ||||||
|  |     } | ||||||
|  |     return(0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecErrorsGetMsg: | ||||||
|  |  * @pos:                the error position. | ||||||
|  |  * | ||||||
|  |  * Gets the known error message at position @pos. | ||||||
|  |  * | ||||||
|  |  * Returns: the known error message or NULL if @pos is greater than | ||||||
|  |  * total number of known error codes. | ||||||
|  |  */ | ||||||
|  | const char* | ||||||
|  | xmlSecErrorsGetMsg(xmlSecSize pos) { | ||||||
|  |     /* could not use asserts here! */ | ||||||
|  |     if(pos < sizeof(xmlSecErrorsTable) / sizeof(xmlSecErrorsTable[0])) { | ||||||
|  |         return(xmlSecErrorsTable[pos].errorMsg); | ||||||
|  |     } | ||||||
|  |     return(NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecError: | ||||||
|  |  * @file:               the error location filename (__FILE__). | ||||||
|  |  * @line:               the error location line number (__LINE__). | ||||||
|  |  * @func:               the error location function (__FUNCTION__). | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @errorSubject:       the error specific error subject (e.g. failed function name). | ||||||
|  |  * @reason:             the error code. | ||||||
|  |  * @msg:                the error message in printf format. | ||||||
|  |  * @...:                the parameters for the @msg. | ||||||
|  |  * | ||||||
|  |  * Reports an error to the default (#xmlSecErrorsDefaultCallback) or | ||||||
|  |  * application specific callback installed using #xmlSecErrorsSetCallback | ||||||
|  |  * function. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xmlSecError(const char* file, int line, const char* func, | ||||||
|  |             const char* errorObject, const char* errorSubject, | ||||||
|  |             int reason, const char* msg, ...) { | ||||||
|  |     if(xmlSecErrorsClbk != NULL) { | ||||||
|  |         xmlChar error_msg[XMLSEC_ERRORS_BUFFER_SIZE]; | ||||||
|  |         int ret; | ||||||
|  |  | ||||||
|  |         if(msg != NULL) { | ||||||
|  |             va_list va; | ||||||
|  |  | ||||||
|  |             va_start(va, msg); | ||||||
|  |             ret = xmlStrVPrintf(error_msg, sizeof(error_msg), msg, va); | ||||||
|  |             if(ret < 0) { | ||||||
|  |                 /* Can't really report an error from an error callback */ | ||||||
|  |                 memcpy(error_msg, fatal_error, sizeof(fatal_error)); | ||||||
|  |             } | ||||||
|  |             error_msg[sizeof(error_msg) - 1] = '\0'; /* just in case */ | ||||||
|  |             va_end(va); | ||||||
|  |         } else { | ||||||
|  |             error_msg[0] = '\0'; | ||||||
|  |         } | ||||||
|  |         xmlSecErrorsClbk(file, line, func, errorObject, errorSubject, reason, (char*)error_msg); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										869
									
								
								experimental/facho-signer/src/xmlsec1/errors_helpers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										869
									
								
								experimental/facho-signer/src/xmlsec1/errors_helpers.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,869 @@ | |||||||
|  | /* | ||||||
|  |  * XML Security Library (http://www.aleksey.com/xmlsec). | ||||||
|  |  * | ||||||
|  |  * Internal header only used during the compilation, | ||||||
|  |  * | ||||||
|  |  * This is free software; see Copyright file in the source | ||||||
|  |  * distribution for preciese wording. | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef __XMLSEC_ERROR_HELPERS_H__ | ||||||
|  | #define __XMLSEC_ERROR_HELPERS_H__ | ||||||
|  |  | ||||||
|  | #include <errno.h> | ||||||
|  | #include <xmlsec/errors.h> | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif /* __cplusplus */ | ||||||
|  |  | ||||||
|  | /********************************************************************** | ||||||
|  |  * | ||||||
|  |  * Error handling macros. | ||||||
|  |  * | ||||||
|  |  **********************************************************************/ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInternalError: | ||||||
|  |  * @errorFunction:      the failed function name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting internal XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInternalError(errorFunction, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     (errorFunction),                        \ | ||||||
|  |                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ | ||||||
|  |                     XMLSEC_ERRORS_NO_MESSAGE                \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInternalError2: | ||||||
|  |  * @errorFunction:      the failed function name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting internal XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInternalError2(errorFunction, errorObject, msg, param) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     (errorFunction),                        \ | ||||||
|  |                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ | ||||||
|  |                     (msg), (param)                          \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInternalError3: | ||||||
|  |  * @errorFunction:      the failed function name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param1. | ||||||
|  |  * @param2:             the extra message param2. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting internal XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInternalError3(errorFunction, errorObject, msg, param1, param2) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     (errorFunction),                        \ | ||||||
|  |                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ | ||||||
|  |                     (msg), (param1), (param2)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInternalError4: | ||||||
|  |  * @errorFunction:      the failed function name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param1. | ||||||
|  |  * @param2:             the extra message param2. | ||||||
|  |  * @param3:             the extra message param3. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting internal XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInternalError4(errorFunction, errorObject, msg, param1, param2, param3) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     (errorFunction),                        \ | ||||||
|  |                     XMLSEC_ERRORS_R_XMLSEC_FAILED,          \ | ||||||
|  |                     (msg), (param1), (param2), (param3)     \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecMallocError: | ||||||
|  |  * @allocSize:          the failed allocation size. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting xmlMalloc() errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecMallocError(allocSize, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     "xmlMalloc",                            \ | ||||||
|  |                     XMLSEC_ERRORS_R_MALLOC_FAILED,          \ | ||||||
|  |                     "size=%lu", (unsigned long)(allocSize)  \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecStrdupError: | ||||||
|  |  * @str:                the failed string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting xmlStrdup() errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecStrdupError(str, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     "xmlStrdup",                            \ | ||||||
|  |                     XMLSEC_ERRORS_R_STRDUP_FAILED,          \ | ||||||
|  |                     "size=%lu", (unsigned long)xmlStrlen(str) \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXmlError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting generic XML errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXmlError(errorFunction, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlGetLastError();        \ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XML_FAILED,        \ | ||||||
|  |                    "xml error: %lu: %s",              \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXmlError2: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting generic XML errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXmlError2(errorFunction, errorObject, msg, param) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlGetLastError();        \ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XML_FAILED,        \ | ||||||
|  |                    msg "; xml error: %lu: %s",        \ | ||||||
|  |                    (param),                           \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXmlParserError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @ctxt:               the parser context. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting XML parser errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXmlParserError(errorFunction, ctxt, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlCtxtGetLastError(ctxt);\ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XML_FAILED,        \ | ||||||
|  |                    "xml error: %lu: %s",              \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXmlParserError2: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @ctxt:               the parser context. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting XML parser errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXmlParserError2(errorFunction, ctxt, errorObject, msg, param) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlCtxtGetLastError(ctxt);\ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XML_FAILED,        \ | ||||||
|  |                    msg "; xml error: %lu: %s",        \ | ||||||
|  |                    (param),                           \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecXsltError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @ctxt:               the parser context. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting XSLT errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecXsltError(errorFunction, ctxt, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlErrorPtr error = xmlGetLastError();        \ | ||||||
|  |         int code = (error != NULL) ? error->code : 0; \ | ||||||
|  |         const char* message = (error != NULL) ? error->message : NULL; \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_XSLT_FAILED,       \ | ||||||
|  |                    "xslt error: %lu: %s",             \ | ||||||
|  |                    (unsigned long)code,               \ | ||||||
|  |                    xmlSecErrorsSafeString(message)    \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecIOError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @name:               the filename, function name, uri, etc. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting IO errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecIOError(errorFunction, name, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_IO_FAILED,         \ | ||||||
|  |                    "name=\"%s\"; errno=%d",           \ | ||||||
|  |                    xmlSecErrorsSafeString(name),      \ | ||||||
|  |                    errno                              \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecNotImplementedError: | ||||||
|  |  * @details:           the additional details. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "not implemented" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecNotImplementedError(details) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ | ||||||
|  |                     "details=%s",                           \ | ||||||
|  |                     xmlSecErrorsSafeString(details)         \ | ||||||
|  |         ) | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @expected:           the expected value. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect exact match. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ | ||||||
|  |                     "invalid size for '%s': actual=%lu is not equal to expected=%lu", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(expected)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeLessThanError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @expected:           the expected value. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect at least the expected size. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeLessThanError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ | ||||||
|  |                     "invalid size for '%s': actual=%lu is less than expected=%lu", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(expected)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeMoreThanError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @expected:           the expected value. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect at most the expected size. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeMoreThanError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ | ||||||
|  |                     "invalid size for '%s': actual=%lu is more than expected=%lu", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(expected)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeNotMultipleOfError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @divider:            the expected divider. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect the size to be a multiple of the divider. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeNotMultipleOfError(name, actual, divider, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,        \ | ||||||
|  |                     "invalid size for '%s': actual=%lu is not a multiple of %lu", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(divider)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidSizeOtherError: | ||||||
|  |  * @msg:                the message about the error. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid size" errors when | ||||||
|  |  * we expect exact match. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidSizeOtherError(msg, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_SIZE,           \ | ||||||
|  |                     "invalid size: %s",                     \ | ||||||
|  |                     xmlSecErrorsSafeString(msg)             \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidDataError: | ||||||
|  |  * @msg:                the msg with explanation. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid data" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidDataError(msg, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_DATA,           \ | ||||||
|  |                     "%s",                                   \ | ||||||
|  |                     xmlSecErrorsSafeString(msg)             \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidStringDataError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value as a string. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid data" errors for string. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidStringDataError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_DATA,           \ | ||||||
|  |                     "invalid data for '%s': actual='%s' and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     xmlSecErrorsSafeString(actual),         \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidIntegerDataError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value as an integer. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid data" errors for integers. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidIntegerDataError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_DATA,           \ | ||||||
|  |                     "invalid data for '%s': actual=%ld and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidIntegerDataError2: | ||||||
|  |  * @name1:              the name of the first variable, parameter, etc. | ||||||
|  |  * @actual1:            the actual first value as an integer. | ||||||
|  |  * @name2:              the name of the second variable, parameter, etc. | ||||||
|  |  * @actual2:            the actual second value as an integer. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid data" errors for integers. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidIntegerDataError2(name1, actual1, name2, actual2, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_DATA,           \ | ||||||
|  |                     "invalid data: actual value '%s'=%ld, actual value '%s'=%ld and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name1),          \ | ||||||
|  |                     (unsigned long)(actual1),               \ | ||||||
|  |                     xmlSecErrorsSafeString(name2),          \ | ||||||
|  |                     (unsigned long)(actual2),               \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTypeError: | ||||||
|  |  * @msg:                the msg with explanation. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid type" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTypeError(msg, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ | ||||||
|  |                     "%s",                                   \ | ||||||
|  |                     xmlSecErrorsSafeString(msg)             \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidStringTypeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value as a string. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid type" errors for string. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidStringTypeError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ | ||||||
|  |                     "invalid type for '%s': actual='%s' and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     xmlSecErrorsSafeString(actual),         \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidIntegerTypeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value as an integer. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid type" errors for integers. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidIntegerTypeError(name, actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ | ||||||
|  |                     "invalid type for '%s': actual=%ld and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name),           \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidIntegerTypeError2: | ||||||
|  |  * @name1:              the name of the first variable, parameter, etc. | ||||||
|  |  * @actual1:            the actual first value as an integer. | ||||||
|  |  * @name2:              the name of the second variable, parameter, etc. | ||||||
|  |  * @actual2:            the actual second value as an integer. | ||||||
|  |  * @expected:           the expected value(s) as a string. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid type" errors for integers. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidIntegerTypeError2(name1, actual1, name2, actual2, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_TYPE,           \ | ||||||
|  |                     "invalid type: actual value '%s'=%ld, actual value '%s'=%ld and expected %s", \ | ||||||
|  |                     xmlSecErrorsSafeString(name1),          \ | ||||||
|  |                     (unsigned long)(actual1),               \ | ||||||
|  |                     xmlSecErrorsSafeString(name2),          \ | ||||||
|  |                     (unsigned long)(actual2),               \ | ||||||
|  |                     (expected)                              \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidNodeError: | ||||||
|  |  * @actualNode:         the actual node. | ||||||
|  |  * @expectedNodeName:   the expected node name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid node errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidNodeError(actualNode, expectedNodeName, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* actualNodeName = xmlSecNodeGetName(actualNode); \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_NODE,      \ | ||||||
|  |                    "actual=%s; expected=%s",          \ | ||||||
|  |                    xmlSecErrorsSafeString(actualNodeName),  \ | ||||||
|  |                    xmlSecErrorsSafeString(expectedNodeName) \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidNodeContentError: | ||||||
|  |  * @node:               the node. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @reason:             the reason why node content is invalid. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid node content errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidNodeContentError(node, errorObject, reason) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* nName = xmlSecNodeGetName(node);  \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_NODE_CONTENT, \ | ||||||
|  |                    "node=%s; reason=%s",              \ | ||||||
|  |                    xmlSecErrorsSafeString(nName),     \ | ||||||
|  |                    xmlSecErrorsSafeString(reason)     \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidNodeAttributeError: | ||||||
|  |  * @node:               the node. | ||||||
|  |  * @attrName:           the attribute name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @reason:             the reason why node content is invalid. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid node attribute errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidNodeAttributeError(node, attrName, errorObject, reason) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* nName = xmlSecNodeGetName(node);  \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE, \ | ||||||
|  |                    "node=%s; attribute=%s; reason=%s",\ | ||||||
|  |                    xmlSecErrorsSafeString(nName),     \ | ||||||
|  |                    xmlSecErrorsSafeString(attrName),  \ | ||||||
|  |                    xmlSecErrorsSafeString(reason)     \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecNodeAlreadyPresentError: | ||||||
|  |  * @parent:             the parent node. | ||||||
|  |  * @nodeName:           the node name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting node already present errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecNodeAlreadyPresentError(parent, nodeName, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* pName = xmlSecNodeGetName(parent);\ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT, \ | ||||||
|  |                    "parent=%s; node=%s",              \ | ||||||
|  |                    xmlSecErrorsSafeString(pName),     \ | ||||||
|  |                    xmlSecErrorsSafeString(nodeName)   \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecUnexpectedNodeError: | ||||||
|  |  * @node:               the node. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid node errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecUnexpectedNodeError(node, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* nName = xmlSecNodeGetName(node);  \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_UNEXPECTED_NODE,   \ | ||||||
|  |                    "node=%s",                         \ | ||||||
|  |                    xmlSecErrorsSafeString(nName)      \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecNodeNotFoundError: | ||||||
|  |  * @errorFunction:      the failed function. | ||||||
|  |  * @startNode:          the search start node. | ||||||
|  |  * @targetNodeName:     the expected child node name. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting node not found errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         const char* startNodeName = xmlSecNodeGetName(startNode); \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)(errorObject),        \ | ||||||
|  |                    (errorFunction),                   \ | ||||||
|  |                    XMLSEC_ERRORS_R_NODE_NOT_FOUND,    \ | ||||||
|  |                    "startNode=%s; target=%s",         \ | ||||||
|  |                    xmlSecErrorsSafeString(startNodeName), \ | ||||||
|  |                    xmlSecErrorsSafeString(targetNodeName) \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTransfromError: | ||||||
|  |  * @transform:          the transform. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid transform errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTransfromError(transform) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)xmlSecTransformGetName(transform), \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_TRANSFORM, \ | ||||||
|  |                    XMLSEC_ERRORS_NO_MESSAGE           \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTransfromError2: | ||||||
|  |  * @transform:          the transform. | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid transform errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTransfromError2(transform, msg, param) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)xmlSecTransformGetName(transform), \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_TRANSFORM, \ | ||||||
|  |                    (msg), (param)                     \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTransfromStatusError: | ||||||
|  |  * @transform:          the transform. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid transform status errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTransfromStatusError(transform) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)xmlSecTransformGetName(transform), \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_STATUS,    \ | ||||||
|  |                    "transformStatus=%d",              \ | ||||||
|  |                    (int)((transform)->status)         \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidTransfromStatusError2: | ||||||
|  |  * @transform:          the transform. | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting an invalid transform status errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidTransfromStatusError2(transform, msg) \ | ||||||
|  |     {                                                 \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,               \ | ||||||
|  |                    (const char*)xmlSecTransformGetName(transform), \ | ||||||
|  |                    NULL,                              \ | ||||||
|  |                    XMLSEC_ERRORS_R_INVALID_STATUS,    \ | ||||||
|  |                    "transformStatus=%ld, msg=%s",     \ | ||||||
|  |                    (long int)((transform)->status),   \ | ||||||
|  |                    msg                                \ | ||||||
|  |         );                                            \ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidKeyDataSizeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @actual:             the actual value. | ||||||
|  |  * @expected:           the expected value(s). | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid keydata size" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidKeyDataSizeError(actual, expected, errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,  \ | ||||||
|  |                     "invalid key data size: actual=%ld and expected=%ld", \ | ||||||
|  |                     (unsigned long)(actual),                \ | ||||||
|  |                     (unsigned long)(expected)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecInvalidZeroKeyDataSizeError: | ||||||
|  |  * @name:               the name of the variable, parameter, etc. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting "invalid keydata size" errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecInvalidZeroKeyDataSizeError(errorObject) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,  \ | ||||||
|  |                     "invalid zero key data size"            \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @details:            the error message. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError(code, errorObject, details) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     "details=%s",                           \ | ||||||
|  |                     xmlSecErrorsSafeString(details)         \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError2: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param:              the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError2(code, errorObject, msg, param) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     (msg), (param)                          \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError3: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param. | ||||||
|  |  * @param2:             the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError3(code, errorObject, msg, param1, param2) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     (msg), (param1), (param2)               \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError4: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param. | ||||||
|  |  * @param2:             the extra message param. | ||||||
|  |  * @param3:             the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError4(code, errorObject, msg, param1, param2, param3) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     (msg), (param1), (param2), (param3)     \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * xmlSecOtherError5: | ||||||
|  |  * @code:               the error code. | ||||||
|  |  * @errorObject:        the error specific error object (e.g. transform, key data, etc). | ||||||
|  |  * @msg:                the extra message. | ||||||
|  |  * @param1:             the extra message param. | ||||||
|  |  * @param2:             the extra message param. | ||||||
|  |  * @param3:             the extra message param. | ||||||
|  |  * @param4:             the extra message param. | ||||||
|  |  * | ||||||
|  |  * Macro. The XMLSec library macro for reporting other XMLSec errors. | ||||||
|  |  */ | ||||||
|  | #define xmlSecOtherError5(code, errorObject, msg, param1, param2, param3, param4) \ | ||||||
|  |         xmlSecError(XMLSEC_ERRORS_HERE,                     \ | ||||||
|  |                     (const char*)(errorObject),             \ | ||||||
|  |                     NULL,                                   \ | ||||||
|  |                     (code),                                 \ | ||||||
|  |                     (msg), (param1), (param2), (param3), (param4) \ | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif /* __cplusplus */ | ||||||
|  |  | ||||||
|  | #endif /* __XMLSEC_ERROR_HELPERS_H__ */ | ||||||
							
								
								
									
										1950
									
								
								experimental/facho-signer/src/xmlsec1/xmltree.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1950
									
								
								experimental/facho-signer/src/xmlsec1/xmltree.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										200
									
								
								experimental/facho-signer/src/xmlusigned.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								experimental/facho-signer/src/xmlusigned.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,200 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <Invoice xmlns="http://www.dian.gov.co/contratos/facturaelectronica/v1" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cdt="urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1" xmlns:clm54217="urn:un:unece:uncefact:codelist:specification:54217:2001" xmlns:clmIANAMIMEMediaType="urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:sts="http://www.dian.gov.co/contratos/facturaelectronica/v1/Structures" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:sig="http://www.w3.org/2000/09/xmldsig#"> | ||||||
|  |   <ext:UBLExtensions> | ||||||
|  |     <ext:UBLExtension> | ||||||
|  |       <ext:ExtensionContent> | ||||||
|  |         <sts:DianExtensions> | ||||||
|  |           <sts:SoftwareSecurityCode schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195">2bd9a18f23cf1188d36888d218e9b0c31df77aa00bc036eaeaa1619184054237eee56d2d8db4ecab0173f65f8dab7753</sts:SoftwareSecurityCode> | ||||||
|  |           <sts:AuthorizationProvider> | ||||||
|  |             <sts:AuthorizationProviderID schemeID="4" schemeName="31" schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195">800197268</sts:AuthorizationProviderID> | ||||||
|  |           </sts:AuthorizationProvider> | ||||||
|  |           <sts:SoftwareProvider> | ||||||
|  |             <sts:ProviderID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195" schemeID="5" schemaName="31">900579212</sts:ProviderID> | ||||||
|  |             <sts:SoftwareID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195">01ab9caa-6838-461e-82fb-da44da36a084</sts:SoftwareID> | ||||||
|  |           </sts:SoftwareProvider> | ||||||
|  |           <sts:InvoiceSource> | ||||||
|  |             <cbc:IdentificationCode>CO</cbc:IdentificationCode> | ||||||
|  |           </sts:InvoiceSource> | ||||||
|  |           <sts:InvoiceControl> | ||||||
|  |             <sts:InvoiceAuthorization>fc8eac422eba16e22ffd8c6f94b3f40a6e38162c</sts:InvoiceAuthorization> | ||||||
|  |             <sts:AuthorizationPeriod> | ||||||
|  |               <cbc:StartDate>2019-01-19</cbc:StartDate> | ||||||
|  |               <cbc:EndDate>2030-01-19</cbc:EndDate> | ||||||
|  |             </sts:AuthorizationPeriod> | ||||||
|  |             <sts:AuthorizedInvoices> | ||||||
|  |               <sts:Prefix>SETP</sts:Prefix> | ||||||
|  |               <sts:From>990000000</sts:From> | ||||||
|  |               <sts:To>995000000</sts:To> | ||||||
|  |             </sts:AuthorizedInvoices> | ||||||
|  |           </sts:InvoiceControl> | ||||||
|  |         </sts:DianExtensions> | ||||||
|  |       </ext:ExtensionContent> | ||||||
|  |     </ext:UBLExtension> | ||||||
|  |   </ext:UBLExtensions> | ||||||
|  |   <cbc:UBLVersionID>UBL 2.1</cbc:UBLVersionID> | ||||||
|  |   <cbc:CustomizationID>10</cbc:CustomizationID> | ||||||
|  |   <cbc:ProfileID>DIAN 2.1</cbc:ProfileID> | ||||||
|  |   <cbc:ProfileExecutionID>2</cbc:ProfileExecutionID> | ||||||
|  |   <cbc:ID>SETP990000001</cbc:ID> | ||||||
|  |   <cbc:UUID schemeID="2" schemeName="CUFE-SHA384">50578625ce1fb2f6bb2bc57b22180d2763c8a868c4e62da72e0e43001f9c7f3459c81e2bf9324830175b1225af37e435</cbc:UUID> | ||||||
|  |   <cbc:DocumentCurrencyCode>COP</cbc:DocumentCurrencyCode> | ||||||
|  |   <cbc:IssueDate>2020-09-05</cbc:IssueDate> | ||||||
|  |   <cbc:IssueTime>22:38:53-05:00</cbc:IssueTime> | ||||||
|  |   <cbc:InvoiceTypeCode listAgencyID="195" listAgencyName="No matching global declaration available for the validation root" listURI="http://www.dian.gov.co">01</cbc:InvoiceTypeCode> | ||||||
|  |   <cbc:LineCountNumeric>1</cbc:LineCountNumeric> | ||||||
|  |   <cac:InvoicePeriod> | ||||||
|  |     <cbc:StartDate>2020-09-05</cbc:StartDate> | ||||||
|  |     <cbc:EndDate>2020-09-05</cbc:EndDate> | ||||||
|  |   </cac:InvoicePeriod> | ||||||
|  |   <cac:AccountingSupplierParty> | ||||||
|  |     <cbc:AdditionalAccountID>1</cbc:AdditionalAccountID> | ||||||
|  |     <cac:Party> | ||||||
|  |       <cac:PartyName> | ||||||
|  |         <cbc:Name>NEUROTEC TECNOLOGIA S.A.S</cbc:Name> | ||||||
|  |       </cac:PartyName> | ||||||
|  |       <cac:PhysicalLocation> | ||||||
|  |         <cac:Address> | ||||||
|  |           <cac:AddressLine> | ||||||
|  |             <cbc:Line/> | ||||||
|  |           </cac:AddressLine> | ||||||
|  |         </cac:Address> | ||||||
|  |       </cac:PhysicalLocation> | ||||||
|  |       <cac:PartyLegalEntity> | ||||||
|  |         <cbc:CompanyID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195" schemeID="5" schemeName="31">900579212</cbc:CompanyID> | ||||||
|  |         <cbc:RegistrationName>NEUROTEC TECNOLOGIA S.A.S</cbc:RegistrationName> | ||||||
|  |         <cac:RegistrationAddress> | ||||||
|  |           <cbc:CityName/> | ||||||
|  |           <cac:AddressLine> | ||||||
|  |             <cbc:Line/> | ||||||
|  |           </cac:AddressLine> | ||||||
|  |           <cac:Country> | ||||||
|  |             <cbc:IdentificationCode>CO</cbc:IdentificationCode> | ||||||
|  |             <cbc:Name>COLOMBIA</cbc:Name> | ||||||
|  |           </cac:Country> | ||||||
|  |         </cac:RegistrationAddress> | ||||||
|  |       </cac:PartyLegalEntity> | ||||||
|  |       <cac:PartyTaxScheme> | ||||||
|  |         <cbc:RegistrationName>NEUROTEC TECNOLOGIA S.A.S</cbc:RegistrationName> | ||||||
|  |         <cbc:CompanyID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195" schemeID="5" schemeName="31">900579212</cbc:CompanyID> | ||||||
|  |         <cbc:TaxLevelCode listName="48">O-07;O-09;O-14;O-48</cbc:TaxLevelCode> | ||||||
|  |         <cac:TaxScheme/> | ||||||
|  |       </cac:PartyTaxScheme> | ||||||
|  |       <cac:Contact> | ||||||
|  |         <cbc:ElectronicMail>sdds@sd.com</cbc:ElectronicMail> | ||||||
|  |       </cac:Contact> | ||||||
|  |     </cac:Party> | ||||||
|  |   </cac:AccountingSupplierParty> | ||||||
|  |   <cac:AccountingCustomerParty> | ||||||
|  |     <cbc:AdditionalAccountID>2</cbc:AdditionalAccountID> | ||||||
|  |     <cac:Party> | ||||||
|  |       <cac:PartyName> | ||||||
|  |         <cbc:Name>facho-customer</cbc:Name> | ||||||
|  |       </cac:PartyName> | ||||||
|  |       <cac:PhysicalLocation> | ||||||
|  |         <cac:Address> | ||||||
|  |           <cac:AddressLine> | ||||||
|  |             <cbc:Line/> | ||||||
|  |           </cac:AddressLine> | ||||||
|  |         </cac:Address> | ||||||
|  |       </cac:PhysicalLocation> | ||||||
|  |       <cac:PartyTaxScheme> | ||||||
|  |         <cbc:CompanyID schemeAgencyName="CO, DIAN (Dirección de Impuestos y Aduanas Nacionales)" schemeAgencyID="195" schemeID="" schemeName="13">43851425</cbc:CompanyID> | ||||||
|  |         <cbc:RegistrationName>facho-customer</cbc:RegistrationName> | ||||||
|  |         <cbc:TaxLevelCode>ZZ</cbc:TaxLevelCode> | ||||||
|  |         <cac:TaxScheme/> | ||||||
|  |       </cac:PartyTaxScheme> | ||||||
|  |       <cac:PartyLegalEntity> | ||||||
|  |         <cbc:RegistrationName>facho-customer</cbc:RegistrationName> | ||||||
|  |         <cac:RegistrationAddress> | ||||||
|  |           <cbc:CityName/> | ||||||
|  |           <cac:AddressLine> | ||||||
|  |             <cbc:Line/> | ||||||
|  |           </cac:AddressLine> | ||||||
|  |           <cac:Country> | ||||||
|  |             <cbc:IdentificationCode>CO</cbc:IdentificationCode> | ||||||
|  |             <cbc:Name>COLOMBIA</cbc:Name> | ||||||
|  |           </cac:Country> | ||||||
|  |         </cac:RegistrationAddress> | ||||||
|  |       </cac:PartyLegalEntity> | ||||||
|  |     </cac:Party> | ||||||
|  |   </cac:AccountingCustomerParty> | ||||||
|  |   <cac:LegalMonetaryTotal> | ||||||
|  |     <cbc:LineExtensionAmount currencyID="COP">100.00</cbc:LineExtensionAmount> | ||||||
|  |     <cbc:TaxExclusiveAmount currencyID="COP">100.00</cbc:TaxExclusiveAmount> | ||||||
|  |     <cbc:TaxInclusiveAmount currencyID="COP">119.00</cbc:TaxInclusiveAmount> | ||||||
|  |     <cbc:ChargeTotalAmount currencyID="COP">19.00</cbc:ChargeTotalAmount> | ||||||
|  |     <cbc:PayableAmount currencyID="COP">119.00</cbc:PayableAmount> | ||||||
|  |   </cac:LegalMonetaryTotal> | ||||||
|  |   <cac:TaxTotal/> | ||||||
|  |   <cac:TaxTotal> | ||||||
|  |     <cac:TaxSubtotal> | ||||||
|  |       <cac:TaxCategory> | ||||||
|  |         <cac:TaxScheme> | ||||||
|  |           <cbc:ID>01</cbc:ID> | ||||||
|  |         </cac:TaxScheme> | ||||||
|  |       </cac:TaxCategory> | ||||||
|  |     </cac:TaxSubtotal> | ||||||
|  |     <cbc:TaxAmount>19.00</cbc:TaxAmount> | ||||||
|  |   </cac:TaxTotal> | ||||||
|  |   <cac:TaxTotal> | ||||||
|  |     <cac:TaxSubtotal> | ||||||
|  |       <cac:TaxCategory> | ||||||
|  |         <cac:TaxScheme> | ||||||
|  |           <cbc:ID>04</cbc:ID> | ||||||
|  |         </cac:TaxScheme> | ||||||
|  |       </cac:TaxCategory> | ||||||
|  |     </cac:TaxSubtotal> | ||||||
|  |     <cbc:TaxAmount>0.00</cbc:TaxAmount> | ||||||
|  |   </cac:TaxTotal> | ||||||
|  |   <cac:TaxTotal> | ||||||
|  |     <cac:TaxSubtotal> | ||||||
|  |       <cac:TaxCategory> | ||||||
|  |         <cac:TaxScheme> | ||||||
|  |           <cbc:ID>03</cbc:ID> | ||||||
|  |         </cac:TaxScheme> | ||||||
|  |       </cac:TaxCategory> | ||||||
|  |     </cac:TaxSubtotal> | ||||||
|  |     <cbc:TaxAmount>0.00</cbc:TaxAmount> | ||||||
|  |   </cac:TaxTotal> | ||||||
|  |   <cac:InvoiceLine> | ||||||
|  |     <cbc:ID>1</cbc:ID> | ||||||
|  |     <cbc:InvoicedQuantity unitCode="NAR">1</cbc:InvoicedQuantity> | ||||||
|  |     <cbc:LineExtensionAmount currencyID="COP">100.0</cbc:LineExtensionAmount> | ||||||
|  |     <cac:TaxTotal> | ||||||
|  |       <cbc:TaxAmount currencyID="COP">19.0</cbc:TaxAmount> | ||||||
|  |       <cac:TaxSubtotal> | ||||||
|  |         <cbc:TaxableAmount currencyID="COP">100.0</cbc:TaxableAmount> | ||||||
|  |         <cbc:TaxAmount currencyID="COP">19.0</cbc:TaxAmount> | ||||||
|  |         <cac:TaxCategory> | ||||||
|  |           <cbc:Percent>19.0</cbc:Percent> | ||||||
|  |           <cac:TaxScheme> | ||||||
|  |             <cbc:ID>01</cbc:ID> | ||||||
|  |             <cbc:Name>IVA</cbc:Name> | ||||||
|  |           </cac:TaxScheme> | ||||||
|  |         </cac:TaxCategory> | ||||||
|  |       </cac:TaxSubtotal> | ||||||
|  |     </cac:TaxTotal> | ||||||
|  |     <cac:PricingReference> | ||||||
|  |       <cac:AlternativeConditionPrice> | ||||||
|  |         <cbc:PriceAmount currencyID="COP">100.0</cbc:PriceAmount> | ||||||
|  |         <cbc:PriceTypeCode>01</cbc:PriceTypeCode> | ||||||
|  |         <cbc:PriceType>x</cbc:PriceType> | ||||||
|  |       </cac:AlternativeConditionPrice> | ||||||
|  |     </cac:PricingReference> | ||||||
|  |     <cac:Item> | ||||||
|  |       <cbc:Description>test</cbc:Description> | ||||||
|  |       <cac:StandardItemIdentification> | ||||||
|  |         <cbc:ID>9999</cbc:ID> | ||||||
|  |       </cac:StandardItemIdentification> | ||||||
|  |     </cac:Item> | ||||||
|  |     <cac:Price> | ||||||
|  |       <cbc:PriceAmount currencyID="COP">100.0</cbc:PriceAmount> | ||||||
|  |     </cac:Price> | ||||||
|  |   </cac:InvoiceLine> | ||||||
|  |   <cac:PaymentMeans> | ||||||
|  |     <cbc:ID>1</cbc:ID> | ||||||
|  |     <cbc:PaymentMeansCode>10</cbc:PaymentMeansCode> | ||||||
|  |     <cbc:PaymentDueDate>2020-09-05</cbc:PaymentDueDate> | ||||||
|  |     <cbc:PaymentID>1</cbc:PaymentID> | ||||||
|  |   </cac:PaymentMeans> | ||||||
|  | </Invoice> | ||||||
							
								
								
									
										7
									
								
								experimental/facho-wasm/xmlsec-wasm/build.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								experimental/facho-wasm/xmlsec-wasm/build.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | #!/bin/sh | ||||||
|  |  | ||||||
|  | set -ex | ||||||
|  |  | ||||||
|  | sh build_openssl.sh | ||||||
|  | sh build_libxml2.sh | ||||||
|  | sh build_xmlsec.sh | ||||||
							
								
								
									
										21
									
								
								experimental/facho-wasm/xmlsec-wasm/build_libxml2.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								experimental/facho-wasm/xmlsec-wasm/build_libxml2.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | #!/bin/sh | ||||||
|  |  | ||||||
|  | LIBXML2_VERSION=2.9.12 | ||||||
|  |  | ||||||
|  | tar xf libxml2-${LIBXML2_VERSION}.tar.gz | ||||||
|  |  | ||||||
|  | mv libxml2-${LIBXML2_VERSION} libxml2 | ||||||
|  |  | ||||||
|  | pushd libxml2 | ||||||
|  |  | ||||||
|  | wasiconfigure  ./configure --enable-static --without-http --without-ftp --without-modules --without-python --without-zlib --without-lzma --without-threads --host=x86_64 | ||||||
|  |  | ||||||
|  | wasimake make clean | ||||||
|  | wasimake make -j4 | ||||||
|  |  | ||||||
|  | popd | ||||||
|  |  | ||||||
|  | mkdir -p vendor/libxml2/lib | ||||||
|  | mkdir -p vendor/libxml2/include | ||||||
|  | cp -r libxml2/include/libxml2 vendor/libxml2/include | ||||||
|  | cp -r libxml2/.libs/libxml2.a vendor/libxml2/lib | ||||||
							
								
								
									
										41
									
								
								experimental/facho-wasm/xmlsec-wasm/build_openssl.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								experimental/facho-wasm/xmlsec-wasm/build_openssl.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | # TOMADO DE: https://github.com/voltbuilder/openssl-wasm | ||||||
|  |  | ||||||
|  | OPENSSL_VERSION=1.1.1l | ||||||
|  |  | ||||||
|  | # get the source | ||||||
|  | tar xf openssl-${OPENSSL_VERSION}.tar.gz | ||||||
|  |  | ||||||
|  | patch -p0 < openssl-${OPENSSL_VERSION}.patch | ||||||
|  |  | ||||||
|  | cd openssl-${OPENSSL_VERSION} | ||||||
|  | make clean | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | # why ./Configure instead of ./config? We want to force using the generic gcc profile which is more conservative than linux-x32 | ||||||
|  | # -no-sock - we don't have sockets in WASI | ||||||
|  | # new -no-ui-console - sdk 12 has no termios??? | ||||||
|  | # check in 12 -DHAVE_FORK=0 - no fork() in WASI | ||||||
|  | # new -D_WASI_EMULATED_MMAN - works with the library below to enable WASI mman emulation | ||||||
|  | # new -D_WASI_EMULATED_SIGNAL - with sdk 12 | ||||||
|  | # new -DOPENSSL_NO_SECURE_MEMORY - wasi doesn't have secure mem (madvise, mlock, etc...) | ||||||
|  | # new -DNO_SYSLOG - get rid of need for patch above | ||||||
|  | # --with-rand-seed=getrandom (needed to force using getentropy because WASI has no /dev/random or getrandom) | ||||||
|  | wasiconfigure ./Configure gcc -no-sock -no-ui-console -DHAVE_FORK=0 -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_SIGNAL -DOPENSSL_NO_SECURE_MEMORY -DNO_SYSLOG --with-rand-seed=getrandom | ||||||
|  |  | ||||||
|  | # enables stuff from mman.h (see define above) also add -lwasi-emulated-signal | ||||||
|  | #sed -i -e "s/CNF_EX_LIBS=/CNF_EX_LIBS=-lwasi-emulated-mman -lwasi-emulated-signal /g" Makefile | ||||||
|  |  | ||||||
|  | # build! | ||||||
|  | wasimake make -j4 build_generated libssl.a libcrypto.a | ||||||
|  |  | ||||||
|  | rm -rf ../vendor/openssl/include | ||||||
|  | mkdir -p ../vendor/openssl/include | ||||||
|  | cp -R include/openssl ../vendor/openssl/include | ||||||
|  |  | ||||||
|  | mkdir -p ../vendor/openssl/lib/ | ||||||
|  | cp libssl.a ../vendor/openssl/lib/ | ||||||
|  | cp libcrypto.a ../vendor/openssl/lib/ | ||||||
|  |  | ||||||
|  | exit 0 | ||||||
							
								
								
									
										14
									
								
								experimental/facho-wasm/xmlsec-wasm/build_xmlsec.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								experimental/facho-wasm/xmlsec-wasm/build_xmlsec.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | #!/bin/sh | ||||||
|  |  | ||||||
|  | XMLSEC1_VERSION=1.2.33 | ||||||
|  |  | ||||||
|  | tar xf xmlsec1-${XMLSEC1_VERSION}.tar.gz | ||||||
|  |  | ||||||
|  | cd xmlsec1-${XMLSEC1_VERSION} | ||||||
|  |  | ||||||
|  | cp -r ../libxml2 . | ||||||
|  | cp -r ../vendor . | ||||||
|  |  | ||||||
|  | wasiconfigure ./configure --with-libxml-src=`pwd`/libxml2 --with-openssl=`pwd`/vendor/openssl  --enable-static-linking  --disable-folders-search --disable-apps --disable-apps-crypto-dl --disable-crypto-dl | ||||||
|  |  | ||||||
|  | wasimake make -j4 | ||||||
							
								
								
									
										6
									
								
								experimental/facho-wasm/xmlsec-wasm/examples/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								experimental/facho-wasm/xmlsec-wasm/examples/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | # ejemplo | ||||||
|  |  | ||||||
|  | ~~~ | ||||||
|  | $ bash build.sh | ||||||
|  | $ wasirun ./a.out sign1-tmpl.xml example.key | ||||||
|  | ~~~ | ||||||
							
								
								
									
										12
									
								
								experimental/facho-wasm/xmlsec-wasm/examples/build.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								experimental/facho-wasm/xmlsec-wasm/examples/build.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | cp ../vendor/openssl/lib/*.a . | ||||||
|  | cp ../xmlsec1-1.2.33/src/.libs/*.a . | ||||||
|  | cp ../xmlsec1-1.2.33/src/openssl/.libs/*.a . | ||||||
|  | cp ../libxml2/.libs/libxml2.a . | ||||||
|  |  | ||||||
|  | mkdir -p include | ||||||
|  |  | ||||||
|  | cp -r ../libxml2/include/libxml include/ | ||||||
|  | cp -r ../xmlsec1-1.2.33/include/xmlsec include/ | ||||||
|  | cp -r ../vendor/openssl/include/* include/ | ||||||
|  |  | ||||||
|  | wasicc -Iinclude libxml2.a libcrypto.a libssl.a libxmlsec1.a libxmlsec1-openssl.a sign.c  | ||||||
							
								
								
									
										216
									
								
								experimental/facho-wasm/xmlsec-wasm/examples/sign.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								experimental/facho-wasm/xmlsec-wasm/examples/sign.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,216 @@ | |||||||
|  | /**  | ||||||
|  |  * XML Security Library example: Signing a template file. | ||||||
|  |  *  | ||||||
|  |  * Signs a template file using a key from PEM file | ||||||
|  |  *  | ||||||
|  |  * Usage:  | ||||||
|  |  *      ./sign1 <xml-tmpl> <pem-key>  | ||||||
|  |  * | ||||||
|  |  * Example: | ||||||
|  |  *      ./sign1 sign1-tmpl.xml rsakey.pem > sign1-res.xml | ||||||
|  |  * | ||||||
|  |  * The result signature could be validated using verify1 example: | ||||||
|  |  *      ./verify1 sign1-res.xml rsapub.pem | ||||||
|  |  * | ||||||
|  |  * This is free software; see Copyright file in the source | ||||||
|  |  * distribution for preciese wording. | ||||||
|  |  *  | ||||||
|  |  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. | ||||||
|  |  */ | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <assert.h> | ||||||
|  |  | ||||||
|  | #include <libxml/tree.h> | ||||||
|  | #include <libxml/xmlmemory.h> | ||||||
|  | #include <libxml/parser.h> | ||||||
|  |  | ||||||
|  | #define XMLSEC_NO_XSLT | ||||||
|  | #define XMLSEC_CRYPTO_OPENSSL | ||||||
|  |  | ||||||
|  | #ifndef XMLSEC_NO_XSLT | ||||||
|  | #include <libxslt/xslt.h> | ||||||
|  | #include <libxslt/security.h> | ||||||
|  | #endif /* XMLSEC_NO_XSLT */ | ||||||
|  |  | ||||||
|  | #include <xmlsec/xmlsec.h> | ||||||
|  | #include <xmlsec/xmltree.h> | ||||||
|  | #include <xmlsec/xmldsig.h> | ||||||
|  | #include <xmlsec/crypto.h> | ||||||
|  |  | ||||||
|  | int sign_file(const char* tmpl_file, const char* key_file); | ||||||
|  |  | ||||||
|  | int  | ||||||
|  | main(int argc, char **argv) { | ||||||
|  | #ifndef XMLSEC_NO_XSLT | ||||||
|  |     xsltSecurityPrefsPtr xsltSecPrefs = NULL; | ||||||
|  | #endif /* XMLSEC_NO_XSLT */ | ||||||
|  | 	setenv("RANDFILE", "/dev/random", 1); | ||||||
|  |     assert(argv); | ||||||
|  |  | ||||||
|  |     if(argc != 3) { | ||||||
|  |         fprintf(stderr, "Error: wrong number of arguments.\n"); | ||||||
|  |         fprintf(stderr, "Usage: %s <tmpl-file> <key-file>\n", argv[0]); | ||||||
|  |         return(1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     printf("template %s key %s\n", argv[1], argv[2]); | ||||||
|  |     /* Init libxml and libxslt libraries */ | ||||||
|  |     xmlInitParser(); | ||||||
|  |     LIBXML_TEST_VERSION | ||||||
|  |     xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; | ||||||
|  |     xmlSubstituteEntitiesDefault(1); | ||||||
|  | #ifndef XMLSEC_NO_XSLT | ||||||
|  |     xmlIndentTreeOutput = 1;  | ||||||
|  | #endif /* XMLSEC_NO_XSLT */ | ||||||
|  |  | ||||||
|  |     /* Init libxslt */ | ||||||
|  | #ifndef XMLSEC_NO_XSLT | ||||||
|  |     /* disable everything */ | ||||||
|  |     xsltSecPrefs = xsltNewSecurityPrefs();  | ||||||
|  |     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_READ_FILE,        xsltSecurityForbid); | ||||||
|  |     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_WRITE_FILE,       xsltSecurityForbid); | ||||||
|  |     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid); | ||||||
|  |     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_READ_NETWORK,     xsltSecurityForbid); | ||||||
|  |     xsltSetSecurityPrefs(xsltSecPrefs,  XSLT_SECPREF_WRITE_NETWORK,    xsltSecurityForbid); | ||||||
|  |     xsltSetDefaultSecurityPrefs(xsltSecPrefs);  | ||||||
|  | #endif /* XMLSEC_NO_XSLT */                 | ||||||
|  |  | ||||||
|  |     /* Init xmlsec library */ | ||||||
|  |     if(xmlSecInit() < 0) { | ||||||
|  |         fprintf(stderr, "Error: xmlsec initialization failed.\n"); | ||||||
|  |         return(-1); | ||||||
|  |     } | ||||||
|  | 	puts("done xmlSecInit"); | ||||||
|  |  | ||||||
|  |     /* Check loaded library version */ | ||||||
|  |     if(xmlSecCheckVersion() != 1) { | ||||||
|  |         fprintf(stderr, "Error: loaded xmlsec library version is not compatible.\n"); | ||||||
|  |         return(-1); | ||||||
|  |     } | ||||||
|  | 	puts("done xmlSecCheckVersion"); | ||||||
|  |     /* Load default crypto engine if we are supporting dynamic | ||||||
|  |      * loading for xmlsec-crypto libraries. Use the crypto library | ||||||
|  |      * name ("openssl", "nss", etc.) to load corresponding  | ||||||
|  |      * xmlsec-crypto library. | ||||||
|  |      */ | ||||||
|  | #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING | ||||||
|  |     if(xmlSecCryptoDLLoadLibrary(NULL) < 0) { | ||||||
|  |         fprintf(stderr, "Error: unable to load default xmlsec-crypto library. Make sure\n" | ||||||
|  |                         "that you have it installed and check shared libraries path\n" | ||||||
|  |                         "(LD_LIBRARY_PATH and/or LTDL_LIBRARY_PATH) environment variables.\n"); | ||||||
|  |         return(-1);      | ||||||
|  |     } | ||||||
|  | #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */ | ||||||
|  |  | ||||||
|  |     /* Init crypto library */ | ||||||
|  |     if(xmlSecCryptoAppInit(NULL) < 0) { | ||||||
|  |         fprintf(stderr, "Error: crypto initialization failed.\n"); | ||||||
|  |         return(-1); | ||||||
|  |     } | ||||||
|  | puts("done xmlSecCryptoAppInit"); | ||||||
|  |     /* Init xmlsec-crypto library */ | ||||||
|  |     if(xmlSecCryptoInit() < 0) { | ||||||
|  |         fprintf(stderr, "Error: xmlsec-crypto initialization failed.\n"); | ||||||
|  |         return(-1); | ||||||
|  |     } | ||||||
|  | puts("done xmlSecCryptoInit"); | ||||||
|  |     if(sign_file(argv[1], argv[2]) < 0) { | ||||||
|  |         return(-1); | ||||||
|  |     }     | ||||||
|  |      | ||||||
|  |     /* Shutdown xmlsec-crypto library */ | ||||||
|  |     xmlSecCryptoShutdown(); | ||||||
|  |      | ||||||
|  |     /* Shutdown crypto library */ | ||||||
|  |     xmlSecCryptoAppShutdown(); | ||||||
|  |      | ||||||
|  |     /* Shutdown xmlsec library */ | ||||||
|  |     xmlSecShutdown(); | ||||||
|  |  | ||||||
|  |     /* Shutdown libxslt/libxml */ | ||||||
|  | #ifndef XMLSEC_NO_XSLT | ||||||
|  |     xsltFreeSecurityPrefs(xsltSecPrefs); | ||||||
|  |     xsltCleanupGlobals(); | ||||||
|  | #endif /* XMLSEC_NO_XSLT */ | ||||||
|  |     xmlCleanupParser(); | ||||||
|  |      | ||||||
|  |     return(0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /**  | ||||||
|  |  * sign_file: | ||||||
|  |  * @tmpl_file:          the signature template file name. | ||||||
|  |  * @key_file:           the PEM private key file name. | ||||||
|  |  * | ||||||
|  |  * Signs the #tmpl_file using private key from #key_file. | ||||||
|  |  * | ||||||
|  |  * Returns 0 on success or a negative value if an error occurs. | ||||||
|  |  */ | ||||||
|  | int  | ||||||
|  | sign_file(const char* tmpl_file, const char* key_file) { | ||||||
|  |     xmlDocPtr doc = NULL; | ||||||
|  |     xmlNodePtr node = NULL; | ||||||
|  |     xmlSecDSigCtxPtr dsigCtx = NULL; | ||||||
|  |     int res = -1; | ||||||
|  |      | ||||||
|  |     assert(tmpl_file); | ||||||
|  |     assert(key_file); | ||||||
|  |  | ||||||
|  |     /* load template */ | ||||||
|  |     doc = xmlParseFile(tmpl_file); | ||||||
|  |     if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ | ||||||
|  |         fprintf(stderr, "Error: unable to parse file \"%s\"\n", tmpl_file); | ||||||
|  |         goto done;       | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* find start node */ | ||||||
|  |     node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); | ||||||
|  |     if(node == NULL) { | ||||||
|  |         fprintf(stderr, "Error: start node not found in \"%s\"\n", tmpl_file); | ||||||
|  |         goto done;       | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* create signature context, we don't need keys manager in this example */ | ||||||
|  |     dsigCtx = xmlSecDSigCtxCreate(NULL); | ||||||
|  |     if(dsigCtx == NULL) { | ||||||
|  |         fprintf(stderr,"Error: failed to create signature context\n"); | ||||||
|  |         goto done; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* load private key, assuming that there is not password */ | ||||||
|  |     dsigCtx->signKey = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatPem, NULL, NULL, NULL); | ||||||
|  |     if(dsigCtx->signKey == NULL) { | ||||||
|  |         fprintf(stderr,"Error: failed to load private pem key from \"%s\"\n", key_file); | ||||||
|  |         goto done; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* set key name to the file name, this is just an example! */ | ||||||
|  |     if(xmlSecKeySetName(dsigCtx->signKey, key_file) < 0) { | ||||||
|  |         fprintf(stderr,"Error: failed to set key name for key from \"%s\"\n", key_file); | ||||||
|  |         goto done; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* sign the template */ | ||||||
|  |     if(xmlSecDSigCtxSign(dsigCtx, node) < 0) { | ||||||
|  |         fprintf(stderr,"Error: signature failed\n"); | ||||||
|  |         goto done; | ||||||
|  |     } | ||||||
|  |          | ||||||
|  |     /* print signed document to stdout */ | ||||||
|  |     xmlDocDump(stdout, doc); | ||||||
|  |      | ||||||
|  |     /* success */ | ||||||
|  |     res = 0; | ||||||
|  |  | ||||||
|  | done:     | ||||||
|  |     /* cleanup */ | ||||||
|  |     if(dsigCtx != NULL) { | ||||||
|  |         xmlSecDSigCtxDestroy(dsigCtx); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if(doc != NULL) { | ||||||
|  |         xmlFreeDoc(doc);  | ||||||
|  |     } | ||||||
|  |     return(res); | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								experimental/facho-wasm/xmlsec-wasm/examples/sign1-tmpl.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								experimental/facho-wasm/xmlsec-wasm/examples/sign1-tmpl.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <!--  | ||||||
|  | XML Security Library example: Simple signature template file for sign1 example.  | ||||||
|  | --> | ||||||
|  | <Envelope xmlns="urn:envelope"> | ||||||
|  |   <Data> | ||||||
|  | 	Hello, World! | ||||||
|  |   </Data> | ||||||
|  |   <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> | ||||||
|  |     <SignedInfo> | ||||||
|  |       <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /> | ||||||
|  |       <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> | ||||||
|  |       <Reference URI=""> | ||||||
|  |         <Transforms> | ||||||
|  |           <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> | ||||||
|  |         </Transforms> | ||||||
|  |         <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> | ||||||
|  |         <DigestValue></DigestValue> | ||||||
|  |       </Reference> | ||||||
|  |     </SignedInfo> | ||||||
|  |     <SignatureValue/> | ||||||
|  |     <KeyInfo> | ||||||
|  | 	<KeyName/> | ||||||
|  |     </KeyInfo> | ||||||
|  |   </Signature> | ||||||
|  | </Envelope> | ||||||
|  |  | ||||||
							
								
								
									
										199
									
								
								experimental/facho-wasm/xmlsec-wasm/openssl-1.1.1l.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								experimental/facho-wasm/xmlsec-wasm/openssl-1.1.1l.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,199 @@ | |||||||
|  | diff '--color=auto' -ruN openssl-1.1.1l/crypto/rand/rand_unix.c patch-1.1.1l/crypto/rand/rand_unix.c | ||||||
|  | --- openssl-1.1.1l/crypto/rand/rand_unix.c	2021-08-24 09:38:47.000000000 -0400 | ||||||
|  | +++ patch-1.1.1l/crypto/rand/rand_unix.c	2021-09-12 02:26:35.765347423 -0400 | ||||||
|  | @@ -372,36 +372,36 @@ | ||||||
|  |       * Note: Sometimes getentropy() can be provided but not implemented | ||||||
|  |       * internally. So we need to check errno for ENOSYS | ||||||
|  |       */ | ||||||
|  | -#  if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux) | ||||||
|  | -    extern int getentropy(void *buffer, size_t length) __attribute__((weak)); | ||||||
|  | +/* #  if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux) */ | ||||||
|  | +/*     extern int getentropy(void *buffer, size_t length) __attribute__((weak)); */ | ||||||
|  |   | ||||||
|  | -    if (getentropy != NULL) { | ||||||
|  | +/*     if (getentropy != NULL) { */ | ||||||
|  |          if (getentropy(buf, buflen) == 0) | ||||||
|  |              return (ssize_t)buflen; | ||||||
|  |          if (errno != ENOSYS) | ||||||
|  |              return -1; | ||||||
|  | -    } | ||||||
|  | -#  elif defined(__APPLE__) | ||||||
|  | -    if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess) | ||||||
|  | -	    return (ssize_t)buflen; | ||||||
|  | - | ||||||
|  | -    return -1; | ||||||
|  | -#  else | ||||||
|  | -    union { | ||||||
|  | -        void *p; | ||||||
|  | -        int (*f)(void *buffer, size_t length); | ||||||
|  | -    } p_getentropy; | ||||||
|  | - | ||||||
|  | -    /* | ||||||
|  | -     * We could cache the result of the lookup, but we normally don't | ||||||
|  | -     * call this function often. | ||||||
|  | -     */ | ||||||
|  | -    ERR_set_mark(); | ||||||
|  | -    p_getentropy.p = DSO_global_lookup("getentropy"); | ||||||
|  | -    ERR_pop_to_mark(); | ||||||
|  | -    if (p_getentropy.p != NULL) | ||||||
|  | -        return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1; | ||||||
|  | -#  endif | ||||||
|  | +/*     } */ | ||||||
|  | +/* #  elif defined(__APPLE__) */ | ||||||
|  | +/*     if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess) */ | ||||||
|  | +/* 	    return (ssize_t)buflen; */ | ||||||
|  | + | ||||||
|  | +/*     return -1; */ | ||||||
|  | +/* #  else */ | ||||||
|  | +/*     union { */ | ||||||
|  | +/*         void *p; */ | ||||||
|  | +/*         int (*f)(void *buffer, size_t length); */ | ||||||
|  | +/*     } p_getentropy; */ | ||||||
|  | + | ||||||
|  | +/*     /\* */ | ||||||
|  | +/*      * We could cache the result of the lookup, but we normally don't */ | ||||||
|  | +/*      * call this function often. */ | ||||||
|  | +/*      *\/ */ | ||||||
|  | +/*     ERR_set_mark(); */ | ||||||
|  | +/*     p_getentropy.p = DSO_global_lookup("getentropy"); */ | ||||||
|  | +/*     ERR_pop_to_mark(); */ | ||||||
|  | +/*     if (p_getentropy.p != NULL) */ | ||||||
|  | +/*         return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1; */ | ||||||
|  | +/* #  endif */ | ||||||
|  |   | ||||||
|  |      /* Linux supports this since version 3.17 */ | ||||||
|  |  #  if defined(__linux) && defined(__NR_getrandom) | ||||||
|  | @@ -635,12 +635,12 @@ | ||||||
|  |   */ | ||||||
|  |  size_t rand_pool_acquire_entropy(RAND_POOL *pool) | ||||||
|  |  { | ||||||
|  | -#  if defined(OPENSSL_RAND_SEED_NONE) | ||||||
|  | -    return rand_pool_entropy_available(pool); | ||||||
|  | -#  else | ||||||
|  | +/* #  if defined(OPENSSL_RAND_SEED_NONE) */ | ||||||
|  | +/*     return rand_pool_entropy_available(pool); */ | ||||||
|  | +/* #  else */ | ||||||
|  |      size_t entropy_available; | ||||||
|  |   | ||||||
|  | -#   if defined(OPENSSL_RAND_SEED_GETRANDOM) | ||||||
|  | +/* #   if defined(OPENSSL_RAND_SEED_GETRANDOM) */ | ||||||
|  |      { | ||||||
|  |          size_t bytes_needed; | ||||||
|  |          unsigned char *buffer; | ||||||
|  | @@ -664,7 +664,7 @@ | ||||||
|  |      entropy_available = rand_pool_entropy_available(pool); | ||||||
|  |      if (entropy_available > 0) | ||||||
|  |          return entropy_available; | ||||||
|  | -#   endif | ||||||
|  | +/* #   endif */ | ||||||
|  |   | ||||||
|  |  #   if defined(OPENSSL_RAND_SEED_LIBRANDOM) | ||||||
|  |      { | ||||||
|  | @@ -752,7 +752,7 @@ | ||||||
|  |  #   endif | ||||||
|  |   | ||||||
|  |      return rand_pool_entropy_available(pool); | ||||||
|  | -#  endif | ||||||
|  | +/* #  endif */ | ||||||
|  |  } | ||||||
|  |  # endif | ||||||
|  |  #endif | ||||||
|  | diff '--color=auto' -ruN openssl-1.1.1l/test/drbgtest.c patch-1.1.1l/test/drbgtest.c | ||||||
|  | --- openssl-1.1.1l/test/drbgtest.c	2021-08-24 09:38:47.000000000 -0400 | ||||||
|  | +++ patch-1.1.1l/test/drbgtest.c	2021-09-12 02:07:38.062332301 -0400 | ||||||
|  | @@ -22,8 +22,21 @@ | ||||||
|  |  # include <windows.h> | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +#ifndef HAVE_FORK | ||||||
|  | +# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS) | ||||||
|  | +#  define HAVE_FORK 0 | ||||||
|  | +# else | ||||||
|  | +#  define HAVE_FORK 1 | ||||||
|  | +# endif | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +#if HAVE_FORK | ||||||
|  | +# undef NO_FORK | ||||||
|  | +#else | ||||||
|  | +# define NO_FORK | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  | -#if defined(OPENSSL_SYS_UNIX) | ||||||
|  | +#if defined(OPENSSL_SYS_UNIX) && !defined(NO_FORK) | ||||||
|  |  # include <sys/types.h> | ||||||
|  |  # include <sys/wait.h> | ||||||
|  |  # include <unistd.h> | ||||||
|  | @@ -676,7 +689,7 @@ | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | -#if defined(OPENSSL_SYS_UNIX) | ||||||
|  | +#if defined(OPENSSL_SYS_UNIX) && !defined(NO_FORK) | ||||||
|  |  /* | ||||||
|  |   * Test whether master, public and private DRBG are reseeded after | ||||||
|  |   * forking the process. | ||||||
|  | @@ -795,7 +808,7 @@ | ||||||
|  |          goto error; | ||||||
|  |      reset_drbg_hook_ctx(); | ||||||
|  |   | ||||||
|  | -#if defined(OPENSSL_SYS_UNIX) | ||||||
|  | +#if defined(OPENSSL_SYS_UNIX) && !defined(NO_FORK) | ||||||
|  |      if (!TEST_true(test_drbg_reseed_after_fork(master, public, private))) | ||||||
|  |          goto error; | ||||||
|  |  #endif | ||||||
|  | diff '--color=auto' -ruN openssl-1.1.1l/test/run_tests.pl patch-1.1.1l/test/run_tests.pl | ||||||
|  | --- openssl-1.1.1l/test/run_tests.pl	2021-08-24 09:38:47.000000000 -0400 | ||||||
|  | +++ patch-1.1.1l/test/run_tests.pl	2021-09-12 02:03:57.603451471 -0400 | ||||||
|  | @@ -28,7 +28,7 @@ | ||||||
|  |  my $recipesdir = catdir($srctop, "test", "recipes"); | ||||||
|  |  my $libdir = rel2abs(catdir($srctop, "util", "perl")); | ||||||
|  |   | ||||||
|  | -$ENV{OPENSSL_CONF} = catdir($srctop, "apps", "openssl.cnf"); | ||||||
|  | +$ENV{OPENSSL_CONF} = rel2abs(catdir($srctop, "apps", "openssl.cnf")); | ||||||
|  |   | ||||||
|  |  my %tapargs = | ||||||
|  |      ( verbosity => $ENV{VERBOSE} || $ENV{V} || $ENV{HARNESS_VERBOSE} ? 1 : 0, | ||||||
|  | diff '--color=auto' -ruN openssl-1.1.1l/util/perl/OpenSSL/Test.pm patch-1.1.1l/util/perl/OpenSSL/Test.pm | ||||||
|  | --- openssl-1.1.1l/util/perl/OpenSSL/Test.pm	2021-08-24 09:38:47.000000000 -0400 | ||||||
|  | +++ patch-1.1.1l/util/perl/OpenSSL/Test.pm	2021-09-12 02:01:14.155136681 -0400 | ||||||
|  | @@ -65,7 +65,7 @@ | ||||||
|  |                               rel2abs/; | ||||||
|  |  use File::Path 2.00 qw/rmtree mkpath/; | ||||||
|  |  use File::Basename; | ||||||
|  | -use Cwd qw/getcwd abs_path/; | ||||||
|  | +use Cwd qw/abs_path/; | ||||||
|  |   | ||||||
|  |  my $level = 0; | ||||||
|  |   | ||||||
|  | @@ -904,26 +904,26 @@ | ||||||
|  |      BAIL_OUT("Must run setup() first") if (! $test_name); | ||||||
|  |   | ||||||
|  |      my $f = pop; | ||||||
|  | -    return abs2rel(catfile($directories{SRCTOP},@_,$f),getcwd); | ||||||
|  | +    return catfile($directories{SRCTOP},@_,$f); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  sub __srctop_dir { | ||||||
|  |      BAIL_OUT("Must run setup() first") if (! $test_name); | ||||||
|  |   | ||||||
|  | -    return abs2rel(catdir($directories{SRCTOP},@_), getcwd); | ||||||
|  | +    return catdir($directories{SRCTOP},@_); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  sub __bldtop_file { | ||||||
|  |      BAIL_OUT("Must run setup() first") if (! $test_name); | ||||||
|  |   | ||||||
|  |      my $f = pop; | ||||||
|  | -    return abs2rel(catfile($directories{BLDTOP},@_,$f), getcwd); | ||||||
|  | +    return catfile($directories{BLDTOP},@_,$f); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  sub __bldtop_dir { | ||||||
|  |      BAIL_OUT("Must run setup() first") if (! $test_name); | ||||||
|  |   | ||||||
|  | -    return abs2rel(catdir($directories{BLDTOP},@_), getcwd); | ||||||
|  | +    return catdir($directories{BLDTOP},@_); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  # __exeext is a function that returns the platform dependent file extension | ||||||
							
								
								
									
										98
									
								
								facho/cli.py
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								facho/cli.py
									
									
									
									
									
								
							| @@ -200,6 +200,18 @@ def validate_invoice(invoice_path): | |||||||
|     XSD.validate(content, XSD.UBLInvoice) |     XSD.validate(content, XSD.UBLInvoice) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @click.command() | ||||||
|  | @click.argument('nomina_path') | ||||||
|  | def validate_nominaindividual(nomina_path): | ||||||
|  |     from facho.fe.data.dian import XSD | ||||||
|  |     content = open(nomina_path, 'r').read() | ||||||
|  |     content = content.replace( | ||||||
|  |         'xmlns="http://www.dian.gov.co/contratos/facturaelectronica/v1"', | ||||||
|  |         'xmlns="dian:gov:co:facturaelectronica:NominaIndividual"', | ||||||
|  |     ) | ||||||
|  |     XSD.validate(content, XSD.NominaIndividual) | ||||||
|  |  | ||||||
|  |  | ||||||
| @click.command() | @click.command() | ||||||
| @click.option('--private-key', type=click.Path(exists=True)) | @click.option('--private-key', type=click.Path(exists=True)) | ||||||
| @click.option('--passphrase') | @click.option('--passphrase') | ||||||
| @@ -215,7 +227,7 @@ def sign_xml(private_key, passphrase, xmlfile, ssl=True, use_cache_policy=False, | |||||||
|     if use_cache_policy: |     if use_cache_policy: | ||||||
|         warnings.warn("xades using cache policy") |         warnings.warn("xades using cache policy") | ||||||
|  |  | ||||||
|     signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase, mockpolicy=use_cache_policy) |     signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase, localpolicy=use_cache_policy) | ||||||
|     document = open(xmlfile, 'r').read().encode('utf-8') |     document = open(xmlfile, 'r').read().encode('utf-8') | ||||||
|     with open(output, 'w') as f: |     with open(output, 'w') as f: | ||||||
|         f.write(signer.sign_xml_string(document)) |         f.write(signer.sign_xml_string(document)) | ||||||
| @@ -271,6 +283,65 @@ def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=Tr | |||||||
|         else: |         else: | ||||||
|             DIANWrite(xml, output) |             DIANWrite(xml, output) | ||||||
|  |  | ||||||
|  | @click.command() | ||||||
|  | @click.option('--private-key', type=click.Path(exists=True)) | ||||||
|  | @click.option('--passphrase') | ||||||
|  | @click.option('--ssl/--no-ssl', default=False) | ||||||
|  | @click.option('--sign/--no-sign', default=False) | ||||||
|  | @click.option('--use-cache-policy/--no-use-cache-policy', default=False) | ||||||
|  | @click.argument('scriptname', type=click.Path(exists=True), required=True) | ||||||
|  | @click.argument('output', required=True) | ||||||
|  | def generate_nomina(private_key, passphrase, scriptname, ssl=True, sign=False, use_cache_policy=False, output=None): | ||||||
|  |     """ | ||||||
|  |     imprime xml en pantalla. | ||||||
|  |     SCRIPTNAME espera | ||||||
|  |      def nomina() -> fe.nomina.NominaIndividual | ||||||
|  |      def extensions(fe.nomina.NominaIndividual): -> List[facho.FachoXMLExtension] | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     if not ssl: | ||||||
|  |         disable_ssl() | ||||||
|  |  | ||||||
|  |     import importlib.util | ||||||
|  |  | ||||||
|  |     spec = importlib.util.spec_from_file_location('nomina', scriptname) | ||||||
|  |     module = importlib.util.module_from_spec(spec) | ||||||
|  |     spec.loader.exec_module(module) | ||||||
|  |  | ||||||
|  |     from facho.fe.form_xml import DIANWriteSigned, DIANWrite | ||||||
|  |     import facho.fe | ||||||
|  |  | ||||||
|  |     nomina = module.nomina() | ||||||
|  |  | ||||||
|  |     xml = nomina.toFachoXML() | ||||||
|  |  | ||||||
|  |     extensions = module.extensions(nomina) | ||||||
|  |     for extension in extensions: | ||||||
|  |         xml.add_extension(extension) | ||||||
|  |  | ||||||
|  |     if sign: | ||||||
|  |         DIANWriteSigned(xml, output, private_key, passphrase, use_cache_policy, dian_signer=facho.fe.nomina.DianXMLExtensionSigner) | ||||||
|  |     else: | ||||||
|  |         DIANWrite(xml, output) | ||||||
|  |  | ||||||
|  | @click.command() | ||||||
|  | @click.option('--private-key', required=True) | ||||||
|  | @click.option('--public-key', required=True) | ||||||
|  | @click.option('--habilitacion/--produccion', default=False) | ||||||
|  | @click.option('--password') | ||||||
|  | @click.argument('filename', required=True) | ||||||
|  | @click.argument('zipfile', type=click.Path(exists=True)) | ||||||
|  | def soap_send_nomina_sync(private_key, public_key, habilitacion, password, filename, zipfile): | ||||||
|  |     from facho.fe.client import dian | ||||||
|  |  | ||||||
|  |     client = dian.DianSignatureClient(private_key, public_key, password=password) | ||||||
|  |     req = dian.SendNominaSync | ||||||
|  |     if habilitacion: | ||||||
|  |         req = dian.Habilitacion.SendNominaSync | ||||||
|  |     resp = client.request(req( | ||||||
|  |         open(zipfile, 'rb').read() | ||||||
|  |     )) | ||||||
|  |     print(resp) | ||||||
|  |  | ||||||
| @click.command() | @click.command() | ||||||
| @click.option('--private-key', type=click.Path(exists=True)) | @click.option('--private-key', type=click.Path(exists=True)) | ||||||
| @@ -287,7 +358,7 @@ def sign_verify_xml(private_key, passphrase, xmlfile, ssl=True, use_cache_policy | |||||||
|         warnings.warn("xades using cache policy") |         warnings.warn("xades using cache policy") | ||||||
|  |  | ||||||
|     print("THIS ONLY WORKS FOR DOCUMENTS GENERATE WITH FACHO") |     print("THIS ONLY WORKS FOR DOCUMENTS GENERATE WITH FACHO") | ||||||
|     signer = fe.DianXMLExtensionSignerVerifier(private_key, passphrase=passphrase, mockpolicy=use_cache_policy) |     signer = fe.DianXMLExtensionSignerVerifier(private_key, passphrase=passphrase, localpolicy=use_cache_policy) | ||||||
|     document = open(xmlfile, 'r').read().encode('utf-8') |     document = open(xmlfile, 'r').read().encode('utf-8') | ||||||
|  |  | ||||||
|     if signer.verify_string(document): |     if signer.verify_string(document): | ||||||
| @@ -295,6 +366,25 @@ def sign_verify_xml(private_key, passphrase, xmlfile, ssl=True, use_cache_policy | |||||||
|     else: |     else: | ||||||
|         print("-INVALID") |         print("-INVALID") | ||||||
|  |  | ||||||
|  | @click.command() | ||||||
|  | @click.option('--software-id') | ||||||
|  | @click.option('--software-pin') | ||||||
|  | @click.option('--nit') | ||||||
|  | @click.option('--dv') | ||||||
|  | @click.option('--output-zippath') | ||||||
|  | def generate_nomina_habilitacion(software_id, software_pin, nit, dv, output_zippath): | ||||||
|  |     from facho import fe | ||||||
|  |  | ||||||
|  |     generador = fe.nomina.habilitacion.Habilitacion( | ||||||
|  |         fe.nomina.habilitacion.Habilitacion.Metadata( | ||||||
|  |             software_id=software_id, | ||||||
|  |             software_pin=software_pin, | ||||||
|  |             nit=nit, | ||||||
|  |             dv=dv | ||||||
|  |         ) | ||||||
|  |     ) | ||||||
|  |     generador.generar(output_zippath) | ||||||
|  |  | ||||||
| @click.group() | @click.group() | ||||||
| def main(): | def main(): | ||||||
|     pass |     pass | ||||||
| @@ -310,3 +400,7 @@ main.add_command(generate_invoice) | |||||||
| main.add_command(validate_invoice) | main.add_command(validate_invoice) | ||||||
| main.add_command(sign_xml) | main.add_command(sign_xml) | ||||||
| main.add_command(sign_verify_xml) | main.add_command(sign_verify_xml) | ||||||
|  | main.add_command(generate_nomina) | ||||||
|  | main.add_command(soap_send_nomina_sync) | ||||||
|  | main.add_command(validate_nominaindividual) | ||||||
|  | main.add_command(generate_nomina_habilitacion) | ||||||
|   | |||||||
							
								
								
									
										254
									
								
								facho/facho.py
									
									
									
									
									
								
							
							
						
						
									
										254
									
								
								facho/facho.py
									
									
									
									
									
								
							| @@ -4,6 +4,13 @@ | |||||||
| from lxml import etree | from lxml import etree | ||||||
| from lxml.etree import Element, SubElement, tostring | from lxml.etree import Element, SubElement, tostring | ||||||
| import re | import re | ||||||
|  | from collections import defaultdict | ||||||
|  | from copy import deepcopy | ||||||
|  | from pprint import pprint | ||||||
|  |  | ||||||
|  | class FachoValueInvalid(Exception): | ||||||
|  |     def __init__(self, xpath): | ||||||
|  |         super().__init__('FachoValueInvalid invalid xpath %s' % (xpath)) | ||||||
|  |  | ||||||
|  |  | ||||||
| class FachoXMLExtension: | class FachoXMLExtension: | ||||||
| @@ -82,29 +89,63 @@ class LXMLBuilder: | |||||||
|     def append(self, elem, child): |     def append(self, elem, child): | ||||||
|         elem.append(child) |         elem.append(child) | ||||||
|  |  | ||||||
|  |     def append_next(self, elem, slibing): | ||||||
|  |         elem.addnext(slibing) | ||||||
|  |  | ||||||
|     def remove(self, elem): |     def remove(self, elem): | ||||||
|         elem.getparent().remove(elem) |         elem.getparent().remove(elem) | ||||||
|  |  | ||||||
|     def set_text(self, elem, text): |     def set_text(self, elem, text): | ||||||
|         elem.text = text |         elem.text = text | ||||||
|  |  | ||||||
|     def xpath(self, elem, xpath): |     def xpath(self, elem, xpath, multiple=False): | ||||||
|         elems = elem.xpath(xpath, namespaces=self.nsmap) |         elems = elem.xpath(xpath, namespaces=self.nsmap) | ||||||
|         if elems: |         if elems: | ||||||
|             return elems[0] |             if multiple: | ||||||
|  |                 return elems | ||||||
|  |             else: | ||||||
|  |                 return elems[0] | ||||||
|  |  | ||||||
|         return None |         return None | ||||||
|  |  | ||||||
|     def get_text(self, elem): |     def get_text(self, elem): | ||||||
|         return elem.text |         return elem.text | ||||||
|  |  | ||||||
|  |     def get_attribute(self, elem, key): | ||||||
|  |         return elem.attrib[key] | ||||||
|  |  | ||||||
|  |     def is_attribute(self, elem, key, value): | ||||||
|  |         return elem.get(key, False) == value | ||||||
|  |  | ||||||
|     def set_attribute(self,  elem, key, value): |     def set_attribute(self,  elem, key, value): | ||||||
|         elem.attrib[key] = value |         elem.attrib[key] = value | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def tostring(self, elem, **attrs): |     def remove_attributes(cls, elem, keys, exclude = []): | ||||||
|  |         for key in keys: | ||||||
|  |             if key in exclude: | ||||||
|  |                 continue | ||||||
|  |  | ||||||
|  |             try: | ||||||
|  |                 del elem.attrib[key] | ||||||
|  |             except KeyError: | ||||||
|  |                 pass | ||||||
|  |  | ||||||
|  |     @classmethod | ||||||
|  |     def tostring(self, oelem, **attrs): | ||||||
|  |         elem = deepcopy(oelem) | ||||||
|  |  | ||||||
|         attrs['pretty_print'] = attrs.pop('pretty_print', False) |         attrs['pretty_print'] = attrs.pop('pretty_print', False) | ||||||
|         attrs['encoding'] = attrs.pop('encoding', 'UTF-8') |         attrs['encoding'] = attrs.pop('encoding', 'UTF-8') | ||||||
|  |  | ||||||
|  |         for el in elem.getiterator(): | ||||||
|  |             keys = filter(lambda key: key.startswith('facho_'), el.keys()) | ||||||
|  |             self.remove_attributes(el, keys, exclude=['facho_optional']) | ||||||
|  |  | ||||||
|  |             is_optional = el.get('facho_optional', 'False') == 'True' | ||||||
|  |             if is_optional and el.getchildren() == [] and el.keys() == ['facho_optional']: | ||||||
|  |                 el.getparent().remove(el) | ||||||
|  |  | ||||||
|         return tostring(elem, **attrs).decode('utf-8') |         return tostring(elem, **attrs).decode('utf-8') | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -112,22 +153,24 @@ class FachoXML: | |||||||
|     """ |     """ | ||||||
|     Decora XML con funciones de consulta XPATH de un solo elemento |     Decora XML con funciones de consulta XPATH de un solo elemento | ||||||
|     """ |     """ | ||||||
|     def __init__(self, root, builder=None, nsmap=None, fragment_prefix=''): |     def __init__(self, root, builder=None, nsmap=None, fragment_prefix='',fragment_root_element=None): | ||||||
|         if builder is None: |         if builder is None: | ||||||
|             self.builder = LXMLBuilder(nsmap) |             self.builder = LXMLBuilder(nsmap) | ||||||
|         else: |         else: | ||||||
|             self.builder = builder |             self.builder = builder | ||||||
|  |  | ||||||
|         self.nsmap = nsmap |         self.nsmap = nsmap | ||||||
|  |          | ||||||
|         if isinstance(root, str): |         if isinstance(root, str): | ||||||
|             self.root = self.builder.build_element_from_string(root, nsmap) |             self.root = self.builder.build_element_from_string(root, nsmap) | ||||||
|         else: |         else: | ||||||
|             self.root = root |             self.root = root | ||||||
|  |  | ||||||
|  |         self.fragment_root_element = fragment_root_element | ||||||
|         self.fragment_prefix = fragment_prefix |         self.fragment_prefix = fragment_prefix | ||||||
|         self.xpath_for = {} |         self.xpath_for = {} | ||||||
|         self.extensions = [] |         self.extensions = [] | ||||||
|  |         self._validators = defaultdict(lambda: lambda v, attrs: True) | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def from_string(cls, document: str, namespaces: dict() = []) -> 'FachoXML': |     def from_string(cls, document: str, namespaces: dict() = []) -> 'FachoXML': | ||||||
| @@ -153,7 +196,7 @@ class FachoXML: | |||||||
|  |  | ||||||
|         if parent is None: |         if parent is None: | ||||||
|             parent = self.find_or_create_element(xpath, append=append) |             parent = self.find_or_create_element(xpath, append=append) | ||||||
|         return FachoXML(parent, nsmap=self.nsmap, fragment_prefix=root_prefix) |         return FachoXML(parent, nsmap=self.nsmap, fragment_prefix=root_prefix, fragment_root_element=self.root) | ||||||
|  |  | ||||||
|     def register_alias_xpath(self, alias, xpath): |     def register_alias_xpath(self, alias, xpath): | ||||||
|         self.xpath_for[alias] = xpath |         self.xpath_for[alias] = xpath | ||||||
| @@ -169,8 +212,12 @@ class FachoXML: | |||||||
|     def _path_xpath_for(self, xpath): |     def _path_xpath_for(self, xpath): | ||||||
|         return self._normalize_xpath(self._translate_xpath_for(xpath)) |         return self._normalize_xpath(self._translate_xpath_for(xpath)) | ||||||
|  |  | ||||||
|     def placeholder_for(self, xpath, append=False): |     def placeholder_for(self, xpath, append=False, optional=False): | ||||||
|         return self.find_or_create_element(xpath, append) |         elem = self.find_or_create_element(xpath, append) | ||||||
|  |         if optional: | ||||||
|  |             elem.set('facho_optional', 'True') | ||||||
|  |         elem.set('facho_placeholder', 'True') | ||||||
|  |         return elem | ||||||
|  |  | ||||||
|     def replacement_for(self, xpath, new_xpath, content, **attrs): |     def replacement_for(self, xpath, new_xpath, content, **attrs): | ||||||
|         elem = self.get_element(xpath) |         elem = self.get_element(xpath) | ||||||
| @@ -201,9 +248,12 @@ class FachoXML: | |||||||
|         # crea jerarquia segun xpath indicado |         # crea jerarquia segun xpath indicado | ||||||
|         parent = None |         parent = None | ||||||
|         current_elem = self.root |         current_elem = self.root | ||||||
|  |         node_tag = node_paths.pop(-1) | ||||||
|  |  | ||||||
|         for node_path in node_paths: |         for node_path in node_paths: | ||||||
|             node_expr = self.builder.match_expression(node_path) |             node_expr = self.builder.match_expression(node_path) | ||||||
|             node = self.builder.build_from_expression(node_path) |             node = self.builder.build_from_expression(node_path) | ||||||
|  |  | ||||||
|             child = self.builder.find_relative(current_elem, node_expr['path'], self.nsmap) |             child = self.builder.find_relative(current_elem, node_expr['path'], self.nsmap) | ||||||
|  |  | ||||||
|             parent = current_elem |             parent = current_elem | ||||||
| @@ -213,14 +263,56 @@ class FachoXML: | |||||||
|                 self.builder.append(current_elem, node) |                 self.builder.append(current_elem, node) | ||||||
|                 current_elem = node |                 current_elem = node | ||||||
|  |  | ||||||
|         # se fuerza la adicion como un nuevo elemento |         node_expr = self.builder.match_expression(node_tag) | ||||||
|         if append: |         node = self.builder.build_from_expression(node_tag) | ||||||
|             node = self.builder.build_from_expression(node_paths[-1]) |         child = self.builder.find_relative(current_elem, node_expr['path'], self.nsmap) | ||||||
|  |         parent = current_elem | ||||||
|  |         if child is not None: | ||||||
|  |             current_elem = child | ||||||
|  |             | ||||||
|  |         if parent == current_elem: | ||||||
|             self.builder.append(parent, node) |             self.builder.append(parent, node) | ||||||
|             return node |             return node | ||||||
|  |  | ||||||
|  |         # se fuerza la adicion como un nuevo elemento | ||||||
|  |         if append: | ||||||
|  |             last_slibing = None | ||||||
|  |             for child in parent.getchildren(): | ||||||
|  |                 if child.tag == node_tag: | ||||||
|  |                     last_slibing = child | ||||||
|  |  | ||||||
|  |             # si no ahi primos se adiciona como hijo | ||||||
|  |             if last_slibing is None: | ||||||
|  |                 self.builder.append(parent, node) | ||||||
|  |                 return node | ||||||
|  |  | ||||||
|  |             if self.builder.is_attribute(last_slibing, 'facho_placeholder', 'True'): | ||||||
|  |                 self._remove_facho_attributes(last_slibing) | ||||||
|  |                 return last_slibing  | ||||||
|  |             self.builder.append_next(last_slibing, node) | ||||||
|  |             return node | ||||||
|  |  | ||||||
|  |         if child is None: | ||||||
|  |             self.builder.append(current_elem, node) | ||||||
|  |             return node | ||||||
|  |  | ||||||
|  |         self._remove_facho_attributes(current_elem) | ||||||
|         return current_elem |         return current_elem | ||||||
|  |  | ||||||
|  |     def set_element_validator(self, xpath, validator = False): | ||||||
|  |         """ | ||||||
|  |         validador al asignar contenido a xpath indicado | ||||||
|  |  | ||||||
|  |         @param xpath ruta tipo XPath | ||||||
|  |         @param validator callback(content, attributes) | ||||||
|  |         """ | ||||||
|  |  | ||||||
|  |         key = self._path_xpath_for(xpath) | ||||||
|  |         if not validator: | ||||||
|  |             self._validators[key] = lambda v, attrs: True | ||||||
|  |         else: | ||||||
|  |             self._validators[key] = validator | ||||||
|  |          | ||||||
|     def set_element(self, xpath, content, **attrs): |     def set_element(self, xpath, content, **attrs): | ||||||
|         """ |         """ | ||||||
|         asigna contenido ubicado por ruta tipo XPATH. |         asigna contenido ubicado por ruta tipo XPATH. | ||||||
| @@ -232,10 +324,18 @@ class FachoXML: | |||||||
|         format_ = attrs.pop('format_', '%s') |         format_ = attrs.pop('format_', '%s') | ||||||
|         append_ = attrs.pop('append_', False) |         append_ = attrs.pop('append_', False) | ||||||
|         elem = self.find_or_create_element(xpath, append=append_) |         elem = self.find_or_create_element(xpath, append=append_) | ||||||
|  |  | ||||||
|  |         validator = self._validators[xpath] | ||||||
|  |  | ||||||
|  |         if not validator(content, attrs): | ||||||
|  |             raise FachoValueInvalid(xpath) | ||||||
|  |  | ||||||
|         if content: |         if content: | ||||||
|             self.builder.set_text(elem, format_ % content) |             self.builder.set_text(elem, format_ % content) | ||||||
|         for k, v in attrs.items(): |         for k, v in attrs.items(): | ||||||
|             self.builder.set_attribute(elem, k, v) |             if v is not None or str(v) != 'None': | ||||||
|  |                 self.builder.set_attribute(elem, k, str(v)) | ||||||
|  |  | ||||||
|         return elem |         return elem | ||||||
|  |  | ||||||
|     def set_attributes(self, xpath, **attrs): |     def set_attributes(self, xpath, **attrs): | ||||||
| @@ -246,22 +346,136 @@ class FachoXML: | |||||||
|         """ |         """ | ||||||
|         xpath = self._path_xpath_for(xpath) |         xpath = self._path_xpath_for(xpath) | ||||||
|         elem = self.get_element(xpath) |         elem = self.get_element(xpath) | ||||||
|  |  | ||||||
|  |         if elem is None: | ||||||
|  |             raise ValueError("xpath %s not found" % (xpath)) | ||||||
|  |  | ||||||
|         for k, v in attrs.items(): |         for k, v in attrs.items(): | ||||||
|             self.builder.set_attribute(elem, k, v) |             if v is not None or str(v) != 'None': | ||||||
|  |                 self.builder.set_attribute(elem, k, str(v)) | ||||||
|         return self |         return self | ||||||
|  |  | ||||||
|     def get_element(self, xpath): |     def get_element_attribute(self, xpath, attribute, multiple=False): | ||||||
|         xpath = self.fragment_prefix + self._path_xpath_for(xpath) |         elem = self.get_element(xpath, multiple=multiple) | ||||||
|         return self.builder.xpath(self.root, xpath) |  | ||||||
|  |  | ||||||
|     def get_element_text(self, xpath, format_=str): |         if elem is None: | ||||||
|  |             raise ValueError("xpath %s not found" % (xpath)) | ||||||
|  |  | ||||||
|  |         if multiple: | ||||||
|  |             vals = [] | ||||||
|  |             for e in elem: | ||||||
|  |                 vals.append(self.builder.get_attribute(e, attribute)) | ||||||
|  |             return vals | ||||||
|  |         else: | ||||||
|  |             return self.builder.get_attribute(elem, attribute) | ||||||
|  |  | ||||||
|  |     def get_element(self, xpath, multiple=False): | ||||||
|         xpath = self.fragment_prefix + self._path_xpath_for(xpath) |         xpath = self.fragment_prefix + self._path_xpath_for(xpath) | ||||||
|         elem = self.builder.xpath(self.root, xpath) |         return self.builder.xpath(self.root, xpath, multiple=multiple) | ||||||
|         text = self.builder.get_text(elem) |  | ||||||
|         return format_(text) |     def get_element_text(self, xpath, format_=str, multiple=False): | ||||||
|  |         xpath = self.fragment_prefix + self._path_xpath_for(xpath) | ||||||
|  |         # MACHETE(bit4bit) al usar ./ queda ../ | ||||||
|  |         xpath = re.sub(r'^\.\.+', '.', xpath) | ||||||
|  |  | ||||||
|  |         elem = self.builder.xpath(self.root, xpath, multiple=multiple) | ||||||
|  |         if multiple: | ||||||
|  |             vals = [] | ||||||
|  |             for e in elem: | ||||||
|  |                 text = self.builder.get_text(e) | ||||||
|  |                 if text is not None: | ||||||
|  |                     vals.append(format_(text)) | ||||||
|  |             return vals | ||||||
|  |         else: | ||||||
|  |             text = self.builder.get_text(elem) | ||||||
|  |             if text is None: | ||||||
|  |                 return None | ||||||
|  |             return format_(text) | ||||||
|  |  | ||||||
|  |     def get_element_text_or_attribute(self, xpath, default=None, multiple=False, raise_on_fail=False): | ||||||
|  |         parts = xpath.split('/') | ||||||
|  |         is_attribute =  parts[-1].startswith('@') | ||||||
|  |         if is_attribute: | ||||||
|  |             attribute_name = parts.pop(-1).lstrip('@') | ||||||
|  |             element_path = "/".join(parts) | ||||||
|  |             try: | ||||||
|  |                 val = self.get_element_attribute(element_path, attribute_name, multiple=multiple) | ||||||
|  |                 if val is None: | ||||||
|  |                     return default | ||||||
|  |                 return val | ||||||
|  |             except KeyError as e: | ||||||
|  |                 if raise_on_fail: | ||||||
|  |                     raise e | ||||||
|  |                 return default | ||||||
|  |             except ValueError as e: | ||||||
|  |                 if raise_on_fail: | ||||||
|  |                     raise e | ||||||
|  |                 return default | ||||||
|  |         else: | ||||||
|  |             try: | ||||||
|  |                 val = self.get_element_text(xpath, multiple=multiple) | ||||||
|  |                 if val is None: | ||||||
|  |                     return default | ||||||
|  |                 return val | ||||||
|  |             except ValueError as e: | ||||||
|  |                 if raise_on_fail: | ||||||
|  |                     raise e | ||||||
|  |                 return default | ||||||
|  |  | ||||||
|  |     def get_elements_text_or_attributes(self, xpaths, raise_on_fail=True): | ||||||
|  |         """ | ||||||
|  |         returna el contenido o attributos de un conjunto de XPATHS | ||||||
|  |         si algun XPATH es una tupla se retorna el primer elemento del mismo. | ||||||
|  |         """ | ||||||
|  |         vals = [] | ||||||
|  |         for xpath in xpaths: | ||||||
|  |             if isinstance(xpath, tuple): | ||||||
|  |                 val = xpath[0] | ||||||
|  |             else: | ||||||
|  |                 val = self.get_element_text_or_attribute(xpath, raise_on_fail=raise_on_fail) | ||||||
|  |             vals.append(val) | ||||||
|  |         return vals | ||||||
|  |  | ||||||
|  |     def exist_element(self, xpath): | ||||||
|  |         elem = self.get_element(xpath) | ||||||
|  |  | ||||||
|  |         # no se encontro elemento | ||||||
|  |         if elem is None: | ||||||
|  |             return False | ||||||
|  |  | ||||||
|  |         # el placeholder no ha sido populado | ||||||
|  |         if elem.get('facho_placeholder') == 'True': | ||||||
|  |             return False | ||||||
|  |  | ||||||
|  |         # el valor opcional no ha sido populado | ||||||
|  |         if elem.get('facho_optional') == 'True': | ||||||
|  |             return False | ||||||
|  |  | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  |     def _remove_facho_attributes(self, elem): | ||||||
|  |         self.builder.remove_attributes(elem, ['facho_optional', 'facho_placeholder']) | ||||||
|  |  | ||||||
|     def tostring(self, **kw): |     def tostring(self, **kw): | ||||||
|         return self.builder.tostring(self.root, **kw) |         return self.builder.tostring(self.root, **kw) | ||||||
|  |  | ||||||
|  |     def xpath_from_root(self, xpath): | ||||||
|  |         nsmap = {} | ||||||
|  |         ns = '' | ||||||
|  |  | ||||||
|  |         root = self.root | ||||||
|  |         if self.fragment_root_element is not None: | ||||||
|  |             root = self.fragment_root_element | ||||||
|  |              | ||||||
|  |         if isinstance(self.nsmap, dict): | ||||||
|  |             nsmap = dict(map(reversed, self.nsmap.items())) | ||||||
|  |             ns = nsmap[etree.QName(root).namespace] + ':' | ||||||
|  |  | ||||||
|  |         if self.fragment_root_element is not None: | ||||||
|  |             new_xpath = '/' + ns + etree.QName(root).localname + '/' + etree.QName(self.root).localname + '/' + xpath.lstrip('/') | ||||||
|  |         else: | ||||||
|  |             new_xpath = '/' + ns + etree.QName(root).localname + '/' + xpath.lstrip('/') | ||||||
|  |         return new_xpath | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return self.tostring() |         return self.tostring() | ||||||
|   | |||||||
| @@ -12,3 +12,4 @@ from .fe import DianZIP | |||||||
| from .fe import AMBIENTE_PRUEBAS | from .fe import AMBIENTE_PRUEBAS | ||||||
| from .fe import AMBIENTE_PRODUCCION | from .fe import AMBIENTE_PRODUCCION | ||||||
| from . import form_xml | from . import form_xml | ||||||
|  | from . import nomina | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ class SOAPService: | |||||||
|     def get_service(self): |     def get_service(self): | ||||||
|         raise NotImplementedError() |         raise NotImplementedError() | ||||||
|  |  | ||||||
|     def builder_response(self, as_dict): |     def build_response(self, as_dict): | ||||||
|         raise NotImplementedError() |         raise NotImplementedError() | ||||||
|  |  | ||||||
|     def todict(self): |     def todict(self): | ||||||
| @@ -175,7 +175,20 @@ class GetStatusZip(SOAPService): | |||||||
|     def build_response(self, as_dict): |     def build_response(self, as_dict): | ||||||
|         return GetStatusResponse.fromdict(as_dict[0]) |         return GetStatusResponse.fromdict(as_dict[0]) | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class SendNominaSync(SOAPService): | ||||||
|  |     contentFile: bytes | ||||||
|  |  | ||||||
|  |     def get_wsdl(self): | ||||||
|  |         return 'https://vpfe.dian.gov.co/WcfDianCustomerServices.svc?wsdl' | ||||||
|  |  | ||||||
|  |     def get_service(self): | ||||||
|  |         return 'SendNominaSync' | ||||||
|  |  | ||||||
|  |     def build_response(self, as_dict): | ||||||
|  |         return as_dict | ||||||
|  |  | ||||||
|  |      | ||||||
| class Habilitacion: | class Habilitacion: | ||||||
|     WSDL = 'https://vpfe-hab.dian.gov.co/WcfDianCustomerServices.svc?wsdl' |     WSDL = 'https://vpfe-hab.dian.gov.co/WcfDianCustomerServices.svc?wsdl' | ||||||
|  |  | ||||||
| @@ -203,6 +216,9 @@ class Habilitacion: | |||||||
|         def get_wsdl(self): |         def get_wsdl(self): | ||||||
|             return Habilitacion.WSDL |             return Habilitacion.WSDL | ||||||
|  |  | ||||||
|  |     class SendNominaSync(SendNominaSync): | ||||||
|  |         def get_wsdl(self): | ||||||
|  |             return Habilitacion.WSDL | ||||||
|  |  | ||||||
| class DianGateway: | class DianGateway: | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,5 +9,8 @@ def path_for_xsd(dirname, xsdname): | |||||||
|  |  | ||||||
| UBLInvoice= xmlschema.XMLSchema(path_for_xsd('maindoc', 'UBL-Invoice-2.1.xsd')) | UBLInvoice= xmlschema.XMLSchema(path_for_xsd('maindoc', 'UBL-Invoice-2.1.xsd')) | ||||||
|  |  | ||||||
|  | NominaIndividual = xmlschema.XMLSchema(path_for_xsd('nomina', 'NominaIndividualElectronicaXSDV1.0.6.xsd')) | ||||||
|  | NominaIndividualDeAjuste = xmlschema.XMLSchema(path_for_xsd('nomina', 'NominaIndividualDeAjusteElectronicaXSDV1.0.6.xsd')) | ||||||
|  |  | ||||||
| def validate(xml, schema): | def validate(xml, schema): | ||||||
|     schema.validate(xml) |     schema.validate(xml) | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								facho/fe/data/dian/codelist/Idioma-2.1.gc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								facho/fe/data/dian/codelist/Idioma-2.1.gc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <!-- | ||||||
|  |      creado por facho, la dian tiene oficial? | ||||||
|  |      poblar usando anexo tecnico 5.3.1 | ||||||
|  | --> | ||||||
|  | <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | ||||||
|  | 	<Identification> | ||||||
|  | 		<ShortName>Idioma</ShortName> | ||||||
|  | 		<LongName xml:lang="es">Idioma</LongName> | ||||||
|  | 		<Version>1</Version> | ||||||
|  | 	</Identification> | ||||||
|  | 	<ColumnSet> | ||||||
|  | 		<Column Id="iso-639-1" Use="required"> | ||||||
|  | 			<ShortName>ISO 639 1</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Column Id="name" Use="required"> | ||||||
|  | 			<ShortName>Nombre</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Key Id="codeKey"> | ||||||
|  | 			<ShortName>CodeKey</ShortName> | ||||||
|  | 			<ColumnRef Ref="code"/> | ||||||
|  | 		</Key> | ||||||
|  | 	</ColumnSet> | ||||||
|  | 	<SimpleCodeList> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="iso-639-1"> | ||||||
|  | 				<SimpleValue>es</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Español, castellano</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  |         </SimpleCodeList> | ||||||
|  | </gc:CodeList> | ||||||
							
								
								
									
										76
									
								
								facho/fe/data/dian/codelist/PeriodoNomina-2.1.gc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								facho/fe/data/dian/codelist/PeriodoNomina-2.1.gc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <!-- | ||||||
|  |      creado por facho, la dian tiene oficial? | ||||||
|  |      poblar usando anexo tecnico 5.5.1 | ||||||
|  | --> | ||||||
|  | <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | ||||||
|  | 	<Identification> | ||||||
|  | 		<ShortName>PeriodoNomina</ShortName> | ||||||
|  | 		<LongName xml:lang="es">Periodos Nomina</LongName> | ||||||
|  | 		<Version>1</Version> | ||||||
|  | 	</Identification> | ||||||
|  | 	<ColumnSet> | ||||||
|  | 		<Column Id="code" Use="required"> | ||||||
|  | 			<ShortName>Code</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Column Id="name" Use="required"> | ||||||
|  | 			<ShortName>Nombre</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Key Id="codeKey"> | ||||||
|  | 			<ShortName>CodeKey</ShortName> | ||||||
|  | 			<ColumnRef Ref="code"/> | ||||||
|  | 		</Key> | ||||||
|  | 	</ColumnSet> | ||||||
|  | 	<SimpleCodeList> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>1</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Semanal</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>2</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Decenal</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>3</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Catorcenal</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>4</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Quincenal</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>5</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Mensual</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>6</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Otro</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  |         </SimpleCodeList> | ||||||
|  | </gc:CodeList> | ||||||
							
								
								
									
										44
									
								
								facho/fe/data/dian/codelist/SubTipoTrabajador-2.1.gc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								facho/fe/data/dian/codelist/SubTipoTrabajador-2.1.gc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <!-- | ||||||
|  |      creado por facho, la dian tiene oficial? | ||||||
|  |      poblar usando anexo tecnico 5.5.4 | ||||||
|  | --> | ||||||
|  | <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | ||||||
|  | 	<Identification> | ||||||
|  | 		<ShortName>SubTipoTrabajador</ShortName> | ||||||
|  | 		<LongName xml:lang="es">Sub tipos de trabajador</LongName> | ||||||
|  | 		<Version>1</Version> | ||||||
|  | 	</Identification> | ||||||
|  | 	<ColumnSet> | ||||||
|  | 		<Column Id="code" Use="required"> | ||||||
|  | 			<ShortName>Code</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Column Id="name" Use="required"> | ||||||
|  | 			<ShortName>Nombre</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Key Id="codeKey"> | ||||||
|  | 			<ShortName>CodeKey</ShortName> | ||||||
|  | 			<ColumnRef Ref="code"/> | ||||||
|  | 		</Key> | ||||||
|  | 	</ColumnSet> | ||||||
|  | 	<SimpleCodeList> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>00</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>No Aplica</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>01</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Dependiente pensionado por vejez activo</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  |         </SimpleCodeList> | ||||||
|  | </gc:CodeList> | ||||||
							
								
								
									
										68
									
								
								facho/fe/data/dian/codelist/TipoContrato-2.1.gc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								facho/fe/data/dian/codelist/TipoContrato-2.1.gc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <!-- | ||||||
|  |      creado por facho, la dian tiene oficial? | ||||||
|  |      poblar usando anexo tecnico 5.5.2 | ||||||
|  | --> | ||||||
|  | <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | ||||||
|  | 	<Identification> | ||||||
|  | 		<ShortName>TipoContrato</ShortName> | ||||||
|  | 		<LongName xml:lang="es">Tipos de contratos</LongName> | ||||||
|  | 		<Version>1</Version> | ||||||
|  | 	</Identification> | ||||||
|  | 	<ColumnSet> | ||||||
|  | 		<Column Id="code" Use="required"> | ||||||
|  | 			<ShortName>Code</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Column Id="name" Use="required"> | ||||||
|  | 			<ShortName>Nombre</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Key Id="codeKey"> | ||||||
|  | 			<ShortName>CodeKey</ShortName> | ||||||
|  | 			<ColumnRef Ref="code"/> | ||||||
|  | 		</Key> | ||||||
|  | 	</ColumnSet> | ||||||
|  | 	<SimpleCodeList> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>1</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Termino Fijo</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>2</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Término Indefinido</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>3</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Obra o Labor</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>4</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Aprendizaje</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>5</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Pŕacticas o Pasantías</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  |         </SimpleCodeList> | ||||||
|  | </gc:CodeList> | ||||||
							
								
								
									
										156
									
								
								facho/fe/data/dian/codelist/TipoTrabajador-2.1.gc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								facho/fe/data/dian/codelist/TipoTrabajador-2.1.gc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <!-- | ||||||
|  |      creado por facho, la dian tiene oficial? | ||||||
|  |      poblar usando anexo tecnico 5.5.3 | ||||||
|  | --> | ||||||
|  | <gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/"> | ||||||
|  | 	<Identification> | ||||||
|  | 		<ShortName>TipoTrabajador</ShortName> | ||||||
|  | 		<LongName xml:lang="es">Tipos de trabajadores</LongName> | ||||||
|  | 		<Version>1</Version> | ||||||
|  | 	</Identification> | ||||||
|  | 	<ColumnSet> | ||||||
|  | 		<Column Id="code" Use="required"> | ||||||
|  | 			<ShortName>Code</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Column Id="name" Use="required"> | ||||||
|  | 			<ShortName>Nombre</ShortName> | ||||||
|  | 			<Data Type="normalizedString"/> | ||||||
|  | 		</Column> | ||||||
|  | 		<Key Id="codeKey"> | ||||||
|  | 			<ShortName>CodeKey</ShortName> | ||||||
|  | 			<ColumnRef Ref="code"/> | ||||||
|  | 		</Key> | ||||||
|  | 	</ColumnSet> | ||||||
|  | 	<SimpleCodeList> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>01</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Dependiente</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>02</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Servicio domestico</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>04</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Madre comunitaria</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>12</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Aprendices del Sena en etapa lectiva</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>18</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Funcionarios públicos sin tope máximo de ibc</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>19</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Aprendices del SENA en etapa productiva</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>21</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Estudiantes de postgrado en salud</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>22</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Profesor de establecimiento particular</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>23</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Estudiantes aportes solo riesgos laborales</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>30</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Dependiente entidades o universidades públicas con régimen especial en salud</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>31</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Cooperados o pre cooperativas de trabajo asociado</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>47</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Trabajador dependiente de entidad beneficiaria del sistema general de participaciones ‐ aportes patronales</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>51</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Trabajador de tiempo parcial</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>54</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Pre pensionado de entidad en liquidación.</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>56</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Pre pensionado con aporte voluntario a salud</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  | 		<Row> | ||||||
|  | 			<Value ColumnRef="code"> | ||||||
|  | 				<SimpleValue>58</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 			<Value ColumnRef="name"> | ||||||
|  | 				<SimpleValue>Estudiantes de prácticas laborales en el sector público</SimpleValue> | ||||||
|  | 			</Value> | ||||||
|  | 		</Row> | ||||||
|  |         </SimpleCodeList> | ||||||
|  | </gc:CodeList> | ||||||
| @@ -12,9 +12,6 @@ class CodeList: | |||||||
|         self.short_name = '' |         self.short_name = '' | ||||||
|         self.long_name = '' |         self.long_name = '' | ||||||
|         self.version = 1 |         self.version = 1 | ||||||
|         self.canonical_uri = '' |  | ||||||
|         self.canonical_version_uri = '' |  | ||||||
|         self.location_uri = '' |  | ||||||
|  |  | ||||||
|         self.name_column = name_column |         self.name_column = name_column | ||||||
|         self.rows = {} |         self.rows = {} | ||||||
| @@ -27,9 +24,6 @@ class CodeList: | |||||||
|         self.short_name = tree.find('./Identification/ShortName').text |         self.short_name = tree.find('./Identification/ShortName').text | ||||||
|         self.long_name = tree.find('./Identification/LongName').text |         self.long_name = tree.find('./Identification/LongName').text | ||||||
|         self.version = tree.find('./Identification/Version').text |         self.version = tree.find('./Identification/Version').text | ||||||
|         self.canonical_uri = tree.find('./Identification/CanonicalUri').text |  | ||||||
|         self.canonical_version_uri = tree.find('./Identification/CanonicalVersionUri').text |  | ||||||
|         self.location_uri = tree.find('./Identification/LocationUri').text |  | ||||||
|  |  | ||||||
|         #obtener registros... |         #obtener registros... | ||||||
|         for row in tree.findall('./SimpleCodeList/Row'): |         for row in tree.findall('./SimpleCodeList/Row'): | ||||||
| @@ -90,6 +84,7 @@ TipoImpuesto = CodeList(path_for_codelist('TipoImpuesto-2.1.gc'), 'code', 'name' | |||||||
|     .update(CodeList(path_for_codelist('TipoImpuesto-2.1.custom.gc'), 'code', 'name')) |     .update(CodeList(path_for_codelist('TipoImpuesto-2.1.custom.gc'), 'code', 'name')) | ||||||
| CodigoPrecioReferencia = CodeList(path_for_codelist('CodigoPrecioReferencia-2.1.gc'), 'code', 'name') | CodigoPrecioReferencia = CodeList(path_for_codelist('CodigoPrecioReferencia-2.1.gc'), 'code', 'name') | ||||||
| MediosPago = CodeList(path_for_codelist('MediosPago-2.1.gc'), 'code', 'name') | MediosPago = CodeList(path_for_codelist('MediosPago-2.1.gc'), 'code', 'name') | ||||||
|  | FormasPago = CodeList(path_for_codelist('FormasPago-2.1.gc'), 'code', 'name') | ||||||
| RegimenFiscal = CodeList(path_for_codelist('RegimenFiscal-2.1.custom.gc'), 'code', 'name') | RegimenFiscal = CodeList(path_for_codelist('RegimenFiscal-2.1.custom.gc'), 'code', 'name') | ||||||
| TipoOperacionNC = CodeList(path_for_codelist('TipoOperacionNC-2.1.gc'), 'code', 'name') | TipoOperacionNC = CodeList(path_for_codelist('TipoOperacionNC-2.1.gc'), 'code', 'name') | ||||||
| TipoOperacionND = CodeList(path_for_codelist('TipoOperacionND-2.1 - copia.gc'), 'code', 'name') | TipoOperacionND = CodeList(path_for_codelist('TipoOperacionND-2.1 - copia.gc'), 'code', 'name') | ||||||
| @@ -101,3 +96,9 @@ Paises = CodeList(path_for_codelist('Paises-2.1.gc'), 'code', 'name') | |||||||
| TipoIdFiscal = CodeList(path_for_codelist('TipoIdFiscal-2.1.gc'), 'code', 'name') | TipoIdFiscal = CodeList(path_for_codelist('TipoIdFiscal-2.1.gc'), 'code', 'name') | ||||||
| CodigoDescuento = CodeList(path_for_codelist('CodigoDescuento-2.1.gc'), 'code', 'name') | CodigoDescuento = CodeList(path_for_codelist('CodigoDescuento-2.1.gc'), 'code', 'name') | ||||||
| UnidadesMedida = CodeList(path_for_codelist('UnidadesMedida-2.1.gc'), 'code', 'name') | UnidadesMedida = CodeList(path_for_codelist('UnidadesMedida-2.1.gc'), 'code', 'name') | ||||||
|  | TipoTrabajador = CodeList(path_for_codelist('TipoTrabajador-2.1.gc'), 'code', 'name') | ||||||
|  | SubTipoTrabajador = CodeList(path_for_codelist('SubTipoTrabajador-2.1.gc'), 'code', 'name') | ||||||
|  | TipoContrato = CodeList(path_for_codelist('TipoContrato-2.1.gc'), 'code', 'name') | ||||||
|  | PeriodoNomina = CodeList(path_for_codelist('PeriodoNomina-2.1.gc'), 'code', 'name') | ||||||
|  | TipoMoneda = CodeList(path_for_codelist('TipoMoneda-2.1.gc'), 'code', 'name') | ||||||
|  | IdiomaISO6391 = CodeList(path_for_codelist('Idioma-2.1.gc'), 'iso-639-1', 'name') | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| # This file is part of facho.  The COPYRIGHT file at the top level of | # This file is part of facho.  The COPYRIGHT file at the top level of | ||||||
| # this repository contains the full copyright notices and license terms. | # this repository contains the full copyright notices and license terms. | ||||||
|  |  | ||||||
|  | from lxml.builder import E | ||||||
| from ..facho import FachoXML, FachoXMLExtension, LXMLBuilder | from ..facho import FachoXML, FachoXMLExtension, LXMLBuilder | ||||||
| import uuid | import uuid | ||||||
| import xmlsig | import xmlsig | ||||||
| @@ -26,28 +27,31 @@ SCHEME_AGENCY_ATTRS = { | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| pwd = Path(__file__).parent |  | ||||||
| # RESOLUCION 0001: pagina 516 | # RESOLUCION 0001: pagina 516 | ||||||
| POLICY_ID = 'file://'+str(pwd)+'/data/dian/politicadefirmav2.pdf' | POLICY_ID = 'https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf' | ||||||
| POLICY_NAME = u'Política de firma para facturas electrónicas de la República de Colombia.' | POLICY_NAME = u'Política de firma para facturas electrónicas de la República de Colombia.' | ||||||
|  |  | ||||||
|  |  | ||||||
| NAMESPACES = { | NAMESPACES = { | ||||||
|     'facho': 'http://git.disroot.org/Etrivial/facho', |      #'atd': 'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2', | ||||||
|     'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1', |      #'no': 'dian:gov:co:facturaelectronica:NominaIndividual', | ||||||
|     'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', |     'noa': 'dian:gov:co:facturaelectronica:NominaIndividualDeAjuste', | ||||||
|     'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2', |      # 'fe': 'http://www.dian.gov.co/contratos/facturaelectronica/v1', | ||||||
|     'cdt': 'urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1', |     'xs': 'http://www.w3.org/2001/XMLSchema-instance',     | ||||||
|     'clm54217': 'urn:un:unece:uncefact:codelist:specification:54217:2001', |      # 'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', | ||||||
|     'clmIANAMIMEMediaType': 'urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003', |      #'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2', | ||||||
|  |      # 'cdt': 'urn:DocumentInformation:names:specification:ubl:colombia:schema:xsd:DocumentInformationAggregateComponents-1', | ||||||
|  |      # 'clm54217': 'urn:un:unece:uncefact:codelist:specification:54217:2001', | ||||||
|  |      # 'clmIANAMIMEMediaType': 'urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003',`` | ||||||
|     'ext': 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2', |     'ext': 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2', | ||||||
|     'qdt': 'urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2', |      # 'qdt': 'urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2', | ||||||
|     'sts': 'dian:gov:co:facturaelectronica:Structures-2-1', |      # 'sts': 'dian:gov:co:facturaelectronica:Structures-2-1', | ||||||
|     'udt': 'urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2', |      # 'udt': 'urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2', | ||||||
|     'xsi': 'http://www.w3.org/2001/XMLSchema-instance', |      'xsi': 'http://www.w3.org/2001/XMLSchema-instance', | ||||||
|     'xades': 'http://uri.etsi.org/01903/v1.3.2#', |      'xades': 'http://uri.etsi.org/01903/v1.3.2#', | ||||||
|     'ds': 'http://www.w3.org/2000/09/xmldsig#', |      'xades141': 'http://uri.etsi.org/01903/v1.4.1#',     | ||||||
|     'sig': 'http://www.w3.org/2000/09/xmldsig#', |      'ds': 'http://www.w3.org/2000/09/xmldsig#', | ||||||
|  |      #'sig': 'http://www.w3.org/2000/09/xmldsig#', | ||||||
| } | } | ||||||
|  |  | ||||||
| def fe_from_string(document: str) -> FachoXML: | def fe_from_string(document: str) -> FachoXML: | ||||||
| @@ -61,6 +65,7 @@ def mock_xades_policy(): | |||||||
|     with patch('xades.policy.urllib.urlopen') as mock: |     with patch('xades.policy.urllib.urlopen') as mock: | ||||||
|         class UrllibPolicyMock: |         class UrllibPolicyMock: | ||||||
|             def read(self): |             def read(self): | ||||||
|  |                 # Usamos contenido de archivo local | ||||||
|                 cur_dir = os.path.dirname(os.path.abspath(__file__)) |                 cur_dir = os.path.dirname(os.path.abspath(__file__)) | ||||||
|                 data_dir = os.path.join(cur_dir, 'data', 'dian') |                 data_dir = os.path.join(cur_dir, 'data', 'dian') | ||||||
|                 policy_file = os.path.join(data_dir, 'politicadefirmav2.pdf') |                 policy_file = os.path.join(data_dir, 'politicadefirmav2.pdf') | ||||||
| @@ -74,22 +79,19 @@ def mock_xades_policy(): | |||||||
| class FeXML(FachoXML): | class FeXML(FachoXML): | ||||||
|  |  | ||||||
|     def __init__(self, root, namespace): |     def __init__(self, root, namespace): | ||||||
|  |  | ||||||
|         super().__init__("{%s}%s" % (namespace, root), |         super().__init__("{%s}%s" % (namespace, root), | ||||||
|                          nsmap=NAMESPACES) |                          nsmap=NAMESPACES) | ||||||
|  |  | ||||||
|         self._cn = root.rstrip('/') |  | ||||||
|         #self.find_or_create_element(self._cn) |  | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def from_string(cls, document: str) -> 'FeXML': |     def from_string(cls, document: str) -> 'FeXML': | ||||||
|         return super().from_string(document, namespaces=NAMESPACES) |         return super().from_string(document, namespaces=NAMESPACES) | ||||||
|      |      | ||||||
|     def tostring(self, **kw): |     def tostring(self, **kw): | ||||||
|  |         # MACHETE(bit4bit) la DIAN espera que la etiqueta raiz no este en un namespace | ||||||
|         return super().tostring(**kw)\ |         return super().tostring(**kw)\ | ||||||
|             .replace("fe:", "")\ |             .replace("noa:", "")\ | ||||||
|             .replace("xmlns:fe", "xmlns") |             .replace("xmlns:noa", "xmlns")\ | ||||||
|  |             .replace("change", "xsi:schemaLocation") | ||||||
|  |  | ||||||
|  |  | ||||||
| class DianXMLExtensionCUDFE(FachoXMLExtension): | class DianXMLExtensionCUDFE(FachoXMLExtension): | ||||||
| @@ -283,32 +285,35 @@ class DianXMLExtensionSoftwareSecurityCode(FachoXMLExtension): | |||||||
|  |  | ||||||
| class DianXMLExtensionSigner: | class DianXMLExtensionSigner: | ||||||
|  |  | ||||||
|     def __init__(self, pkcs12_path, passphrase=None, mockpolicy=False): |     def __init__(self, pkcs12_path, passphrase=None, localpolicy=True): | ||||||
|         self._pkcs12_data = open(pkcs12_path, 'rb').read() |         self._pkcs12_data = open(pkcs12_path, 'rb').read() | ||||||
|         self._passphrase = None |         self._passphrase = None | ||||||
|         self._mockpolicy = mockpolicy |         self._localpolicy = localpolicy | ||||||
|         if passphrase: |         if passphrase: | ||||||
|             self._passphrase = passphrase.encode('utf-8') |             self._passphrase = passphrase.encode('utf-8') | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def from_bytes(cls, data, passphrase=None, mockpolicy=False): |     def from_bytes(cls, data, passphrase=None, localpolicy=True): | ||||||
|         self = cls.__new__(cls) |         self = cls.__new__(cls) | ||||||
|          |          | ||||||
|         self._pkcs12_data = data |         self._pkcs12_data = data | ||||||
|         self._passphrase = None |         self._passphrase = None | ||||||
|         self._mockpolicy = mockpolicy |         self._localpolicy = localpolicy | ||||||
|         if passphrase: |         if passphrase: | ||||||
|             self._passphrase = passphrase.encode('utf-8') |             self._passphrase = passphrase.encode('utf-8') | ||||||
|              |              | ||||||
|         return self |         return self | ||||||
|      |  | ||||||
|  |     def _element_extension_content(self, fachoxml): | ||||||
|  |         return fachoxml.builder.xpath(fachoxml.root, './ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent') | ||||||
|  |  | ||||||
|     def sign_xml_string(self, document): |     def sign_xml_string(self, document): | ||||||
|         xml = LXMLBuilder.from_string(document) |         xml = LXMLBuilder.from_string(document) | ||||||
|         signature = self.sign_xml_element(xml) |         signature = self.sign_xml_element(xml) | ||||||
|  |  | ||||||
|         fachoxml = FachoXML(xml,nsmap=NAMESPACES) |         fachoxml = FachoXML(xml,nsmap=NAMESPACES) | ||||||
|         #DIAN 1.7.-2020: FAB01 |         #DIAN 1.7.-2020: FAB01 | ||||||
|         extcontent = fachoxml.builder.xpath(fachoxml.root, './ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent') |         extcontent = self._element_extension_content(fachoxml) | ||||||
|         fachoxml.append_element(extcontent, signature) |         fachoxml.append_element(extcontent, signature) | ||||||
|  |  | ||||||
|         return fachoxml.tostring(xml_declaration=True, encoding='UTF-8') |         return fachoxml.tostring(xml_declaration=True, encoding='UTF-8') | ||||||
| @@ -359,7 +364,7 @@ class DianXMLExtensionSigner: | |||||||
|         ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(self._pkcs12_data, |         ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(self._pkcs12_data, | ||||||
|                                                    self._passphrase)) |                                                    self._passphrase)) | ||||||
|  |  | ||||||
|         if self._mockpolicy: |         if self._localpolicy: | ||||||
|             with mock_xades_policy(): |             with mock_xades_policy(): | ||||||
|                 ctx.sign(signature) |                 ctx.sign(signature) | ||||||
|                 ctx.verify(signature) |                 ctx.verify(signature) | ||||||
| @@ -372,7 +377,7 @@ class DianXMLExtensionSigner: | |||||||
|  |  | ||||||
|     def build(self, fachoxml): |     def build(self, fachoxml): | ||||||
|         signature = self.sign_xml_element(fachoxml.root) |         signature = self.sign_xml_element(fachoxml.root) | ||||||
|         extcontent = fachoxml.builder.xpath(fachoxml.root, './ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent') |         extcontent = self._element_extension_content(fachoxml) | ||||||
|         fachoxml.append_element(extcontent, signature) |         fachoxml.append_element(extcontent, signature) | ||||||
|  |  | ||||||
|          |          | ||||||
| @@ -448,7 +453,7 @@ class DianZIP: | |||||||
|         self.zipfile = zipfile.ZipFile(file_like, mode='w', compression=zipfile.ZIP_DEFLATED) |         self.zipfile = zipfile.ZipFile(file_like, mode='w', compression=zipfile.ZIP_DEFLATED) | ||||||
|         self.num_files = 0 |         self.num_files = 0 | ||||||
|  |  | ||||||
|     def add_invoice_xml(self, name, xml_data): |     def add_xml(self, name, xml_data): | ||||||
|         self.num_files += 1 |         self.num_files += 1 | ||||||
|         # TODO cual es la norma para los nombres de archivos? |         # TODO cual es la norma para los nombres de archivos? | ||||||
|         m = hashlib.sha256() |         m = hashlib.sha256() | ||||||
| @@ -459,7 +464,18 @@ class DianZIP: | |||||||
|  |  | ||||||
|         return filename |         return filename | ||||||
|  |  | ||||||
|  |     # DEPRECATED usar add_xml | ||||||
|  |     def add_invoice_xml(self, name, xml_data): | ||||||
|  |         return self.add_xml(name, xml_data) | ||||||
|  |  | ||||||
|     def __enter__(self): |     def __enter__(self): | ||||||
|  |         """ | ||||||
|  |         Facilita el uso de esta manera: | ||||||
|  |          | ||||||
|  |         f = open('xxx', 'rb') | ||||||
|  |         with DianZIP(f) as zip: | ||||||
|  |           zip.add_invoice_xml('name', 'data xml') | ||||||
|  |         """ | ||||||
|         return self |         return self | ||||||
|  |  | ||||||
|     def __exit__(self, type, value, traceback): |     def __exit__(self, type, value, traceback): | ||||||
| @@ -468,34 +484,35 @@ class DianZIP: | |||||||
|  |  | ||||||
| class DianXMLExtensionSignerVerifier: | class DianXMLExtensionSignerVerifier: | ||||||
|  |  | ||||||
|     def __init__(self, pkcs12_path_or_bytes, passphrase=None, mockpolicy=False): |     def __init__(self, pkcs12_path_or_bytes, passphrase=None, localpolicy=True): | ||||||
|         self._pkcs12_path_or_bytes = pkcs12_path_or_bytes |         self._pkcs12_path_or_bytes = pkcs12_path_or_bytes | ||||||
|         self._passphrase = None |         self._passphrase = None | ||||||
|         self._mockpolicy = mockpolicy |         self._localpolicy = localpolicy | ||||||
|         if passphrase: |         if passphrase: | ||||||
|             self._passphrase = passphrase.encode('utf-8') |             self._passphrase = passphrase.encode('utf-8') | ||||||
|  |  | ||||||
|     def verify_string(self, document): |     def verify_string(self, document): | ||||||
|  |         # Obtener FachoXML | ||||||
|         xml = LXMLBuilder.from_string(document) |         xml = LXMLBuilder.from_string(document) | ||||||
|         fachoxml = FachoXML(xml,nsmap=NAMESPACES) |         fachoxml = FachoXML(xml,nsmap=NAMESPACES) | ||||||
|  |  | ||||||
|  |         # Obtener Signature | ||||||
|         signature = fachoxml.builder.xpath(fachoxml.root, '//ds:Signature') |         signature = fachoxml.builder.xpath(fachoxml.root, '//ds:Signature') | ||||||
|         assert signature is not None |         assert signature is not None | ||||||
|  |  | ||||||
|  |         # Se mueve Signature a elemento raiz para realizar verificaion | ||||||
|         signature.getparent().remove(signature) |         signature.getparent().remove(signature) | ||||||
|         fachoxml.root.append(signature) |         fachoxml.root.append(signature) | ||||||
|  |  | ||||||
|         ctx = xades.XAdESContext() |         # Verificar archivo usando Signature | ||||||
|  |  | ||||||
|         pkcs12_data = self._pkcs12_path_or_bytes |         pkcs12_data = self._pkcs12_path_or_bytes | ||||||
|         if isinstance(self._pkcs12_path_or_bytes, str): |         if isinstance(self._pkcs12_path_or_bytes, str): | ||||||
|             pkcs12_data = open(self._pkcs12_path_or_bytes, 'rb').read() |             pkcs12_data = open(self._pkcs12_path_or_bytes, 'rb').read() | ||||||
|  |         ctx = xades.XAdESContext() | ||||||
|         ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(pkcs12_data, |         ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(pkcs12_data, | ||||||
|                                                    self._passphrase)) |                                                    self._passphrase)) | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             if self._mockpolicy: |             if self._localpolicy: | ||||||
|                 with mock_xades_policy(): |                 with mock_xades_policy(): | ||||||
|                     ctx.verify(signature) |                     ctx.verify(signature) | ||||||
|             else: |             else: | ||||||
|   | |||||||
| @@ -2,3 +2,4 @@ from .invoice import * | |||||||
| from .credit_note import * | from .credit_note import * | ||||||
| from .debit_note import * | from .debit_note import * | ||||||
| from .utils import * | from .utils import * | ||||||
|  | from .attached_document import * | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								facho/fe/form_xml/attached_document.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								facho/fe/form_xml/attached_document.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | from .. import fe | ||||||
|  |  | ||||||
|  | __all__ = ['AttachedDocument'] | ||||||
|  |  | ||||||
|  | class AttachedDocument(): | ||||||
|  |  | ||||||
|  |     def __init__(self, id): | ||||||
|  |         schema = 'urn:oasis:names:specification:ubl:schema:xsd:AttachedDocument-2' | ||||||
|  |         self.fexml = fe.FeXML('AttachedDocument', schema) | ||||||
|  |         self.fexml.set_element('./cbc:ID', id) | ||||||
|  |  | ||||||
|  |     def toFachoXML(self): | ||||||
|  |         return self.fexml | ||||||
|  |          | ||||||
| @@ -427,10 +427,10 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|         #tax_amount_for['01']['tax_amount'] = Amount(0.0) |         #tax_amount_for['01']['tax_amount'] = Amount(0.0) | ||||||
|         #tax_amount_for['01']['taxable_amount'] = Amount(0.0) |         #tax_amount_for['01']['taxable_amount'] = Amount(0.0) | ||||||
|         #DIAN 1.7.-2020: FAS07 => Se debe construir estrategia para  su manejo |         #DIAN 1.7.-2020: FAS07 => Se debe construir estrategia para  su manejo | ||||||
|         #tax_amount_for['04']['tax_amount'] = 0.0 |         #tax_amount_for['04']['tax_amount'] += 0.0 | ||||||
|         #tax_amount_for['04']['taxable_amount'] = 0.0 |         #tax_amount_for['04']['taxable_amount'] += 0.0 | ||||||
|         #tax_amount_for['03']['tax_amount'] = 0.0 |         #tax_amount_for['03']['tax_amount'] += 0.0 | ||||||
|         #tax_amount_for['03']['taxable_amount'] = 0.0 |         #tax_amount_for['03']['taxable_amount'] += 0.0 | ||||||
|  |  | ||||||
|         total_tax_amount = Amount(0.0) |         total_tax_amount = Amount(0.0) | ||||||
|  |  | ||||||
| @@ -445,18 +445,18 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|  |  | ||||||
|                 total_tax_amount += subtotal.tax_amount |                 total_tax_amount += subtotal.tax_amount | ||||||
|  |  | ||||||
|         fexml.placeholder_for('./cac:TaxTotal') |         if total_tax_amount != Amount(0.0): | ||||||
|         fexml.set_element_amount('./cac:TaxTotal/cbc:TaxAmount', |             fexml.placeholder_for('./cac:TaxTotal') | ||||||
|                                 total_tax_amount) |             fexml.set_element_amount('./cac:TaxTotal/cbc:TaxAmount', | ||||||
|  |                     total_tax_amount) | ||||||
|  |  | ||||||
|  |          | ||||||
|         for index, item in enumerate(tax_amount_for.items()): |         for index, item in enumerate(tax_amount_for.items()): | ||||||
|             cod_impuesto, amount_of = item |             cod_impuesto, amount_of = item | ||||||
|             next_append = index > 0 |             next_append = index > 0 | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAS01 |             #DIAN 1.7.-2020: FAS01 | ||||||
|             line = fexml.fragment('./cac:TaxTotal', append=next_append) |             line = fexml.fragment('./cac:TaxTotal', append=next_append) | ||||||
|  |  | ||||||
|             #DIAN 1.7.-2020: FAU06 |             #DIAN 1.7.-2020: FAU06 | ||||||
|             tax_amount = amount_of['tax_amount'] |             tax_amount = amount_of['tax_amount'] | ||||||
|             fexml.set_element_amount_for(line, |             fexml.set_element_amount_for(line, | ||||||
| @@ -482,9 +482,12 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|             if percent_for[cod_impuesto]: |             if percent_for[cod_impuesto]: | ||||||
|                 line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent', |                 line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:Percent', | ||||||
|                                  percent_for[cod_impuesto]) |                                  percent_for[cod_impuesto]) | ||||||
|  |                  | ||||||
|             line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', |             line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', | ||||||
|                              cod_impuesto) |                     cod_impuesto) | ||||||
|  |             line.set_element('/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', | ||||||
|  |                     'IVA') | ||||||
|  |    | ||||||
|     # abstract method |     # abstract method | ||||||
|     def tag_document(fexml): |     def tag_document(fexml): | ||||||
|         return 'Invoice' |         return 'Invoice' | ||||||
| @@ -502,7 +505,6 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|         fexml.set_element_amount_for(line, |         fexml.set_element_amount_for(line, | ||||||
|                                      './cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount', |                                      './cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount', | ||||||
|                                      invoice_line.taxable_amount) |                                      invoice_line.taxable_amount) | ||||||
|  |  | ||||||
|         for subtotal in invoice_line.tax.subtotals: |         for subtotal in invoice_line.tax.subtotals: | ||||||
|             line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount', subtotal.tax_amount, currencyID='COP') |             line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount', subtotal.tax_amount, currencyID='COP') | ||||||
|  |  | ||||||
| @@ -513,7 +515,7 @@ class DIANInvoiceXML(fe.FeXML): | |||||||
|                 #DIAN 1.7.-2020: FAX15 |                 #DIAN 1.7.-2020: FAX15 | ||||||
|                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', subtotal.scheme.code) |                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID', subtotal.scheme.code) | ||||||
|                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', subtotal.scheme.name) |                 line.set_element('./cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:Name', subtotal.scheme.name) | ||||||
|  |      | ||||||
|     def set_invoice_lines(fexml, invoice): |     def set_invoice_lines(fexml, invoice): | ||||||
|         next_append = False |         next_append = False | ||||||
|         for index, invoice_line in enumerate(invoice.invoice_lines): |         for index, invoice_line in enumerate(invoice.invoice_lines): | ||||||
|   | |||||||
| @@ -8,8 +8,12 @@ def DIANWrite(xml, filename): | |||||||
|         f.write(document) |         f.write(document) | ||||||
|  |  | ||||||
|          |          | ||||||
| def DIANWriteSigned(xml, filename, private_key, passphrase, use_cache_policy=False): | def DIANWriteSigned(xml, filename, private_key, passphrase, use_cache_policy=False, dian_signer=None): | ||||||
|     document = xml.tostring(xml_declaration=True, encoding='UTF-8').encode('utf-8') |     document = xml.tostring(xml_declaration=True, encoding='UTF-8').encode('utf-8') | ||||||
|     signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase, mockpolicy=use_cache_policy) |     if dian_signer is None: | ||||||
|  |         dian_signer = fe.DianXMLExtensionSigner | ||||||
|  |  | ||||||
|  |     signer = dian_signer(private_key, passphrase=passphrase, localpolicy=use_cache_policy) | ||||||
|  |  | ||||||
|     with open(filename, 'w') as f: |     with open(filename, 'w') as f: | ||||||
|         f.write(signer.sign_xml_string(document)) |         f.write(signer.sign_xml_string(document)) | ||||||
|   | |||||||
							
								
								
									
										627
									
								
								facho/fe/nomina/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										627
									
								
								facho/fe/nomina/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,627 @@ | |||||||
|  | # | ||||||
|  | # Para esta implementacion se usa BDD | ||||||
|  | # ver **test_nomina.py**. | ||||||
|  | # | ||||||
|  | # La idea en general es validar comportamiento desde el XML, | ||||||
|  | # creando las estructuras minimas necesaras. | ||||||
|  |  | ||||||
|  | from dataclasses import dataclass | ||||||
|  | from datetime import datetime | ||||||
|  | import hashlib | ||||||
|  | import typing | ||||||
|  |  | ||||||
|  | from .. import fe | ||||||
|  | from .. import form | ||||||
|  | from ..data.dian import codelist | ||||||
|  |  | ||||||
|  | from .devengado import * | ||||||
|  | from .deduccion import * | ||||||
|  | from .trabajador import * | ||||||
|  | from .empleador import * | ||||||
|  | from .pago import * | ||||||
|  | from .lugar import Lugar | ||||||
|  |  | ||||||
|  | from .amount import Amount | ||||||
|  | from .exception import * | ||||||
|  |  | ||||||
|  | class Fecha: | ||||||
|  |     def __init__(self, fecha): | ||||||
|  |         try: | ||||||
|  |             datetime.strptime(fecha, "%Y-%m-%d") | ||||||
|  |         except ValueError: | ||||||
|  |             raise ValueError("fecha debe ser formato YYYY-MM-DD") | ||||||
|  |         self.value = fecha | ||||||
|  |  | ||||||
|  |     @classmethod | ||||||
|  |     def cast(cls, data, optional=False): | ||||||
|  |         if isinstance(data, str): | ||||||
|  |             return cls(data) | ||||||
|  |         elif isinstance(data, cls): | ||||||
|  |             return data | ||||||
|  |         elif data is None and optional: | ||||||
|  |             return None | ||||||
|  |         else: | ||||||
|  |             raise ValueError('no se logra hacer casting a Fecha') | ||||||
|  |  | ||||||
|  |     def __str__(self): | ||||||
|  |         return self.value | ||||||
|  |  | ||||||
|  | class FechaPago(Fecha): | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_element('./FechaPago', self.value) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class Novedad: | ||||||
|  |     value: False | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_attributes('./Novedad', | ||||||
|  |                                 CUNENov=self.value, | ||||||
|  |                                 ) | ||||||
|  |     def post_apply(self, fexml, scopexml, fragment): | ||||||
|  |         scopexml.set_element('./Novedad', "false") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class NumeroSecuencia: | ||||||
|  |     consecutivo: int | ||||||
|  |     prefijo: str | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         numero = f"{self.prefijo}{self.consecutivo}" | ||||||
|  |         fragment.set_attributes('./NumeroSecuenciaXML', | ||||||
|  |                                 # NIE010 | ||||||
|  |                                 Prefijo=self.prefijo, | ||||||
|  |                                 # NIE011 | ||||||
|  |                                 Consecutivo=self.consecutivo, | ||||||
|  |                                 # NIE012 | ||||||
|  |                                 Numero = numero) | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class Periodo: | ||||||
|  |     fecha_ingreso: typing.Union[str, Fecha] | ||||||
|  |     fecha_liquidacion_inicio: typing.Union[str, Fecha] | ||||||
|  |     fecha_liquidacion_fin: typing.Union[str, Fecha] | ||||||
|  |     fecha_generacion: typing.Union[str, Fecha] | ||||||
|  |  | ||||||
|  |     tiempo_laborado: int = 1 | ||||||
|  |     fecha_retiro: typing.Union[str, Fecha] = None | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         self.fecha_ingreso = Fecha.cast(self.fecha_ingreso) | ||||||
|  |         self.fecha_liquidacion_inicio = Fecha.cast(self.fecha_liquidacion_inicio) | ||||||
|  |         self.fecha_liquidacion_fin = Fecha.cast(self.fecha_liquidacion_fin) | ||||||
|  |         self.fecha_retiro = Fecha.cast(self.fecha_retiro, optional=True) | ||||||
|  |          | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_attributes('./Periodo', | ||||||
|  |                                 #NIE002 | ||||||
|  |                                 FechaIngreso=self.fecha_ingreso, | ||||||
|  |                                 #NIE003 | ||||||
|  |                                 FechaRetiro=self.fecha_retiro, | ||||||
|  |                                 #NIE004 | ||||||
|  |                                 FechaLiquidacionInicio=self.fecha_liquidacion_inicio, | ||||||
|  |                                 #NIE005 | ||||||
|  |                                 FechaLiquidacionFin=self.fecha_liquidacion_fin, | ||||||
|  |                                 #NIE006 | ||||||
|  |                                 TiempoLaborado=self.tiempo_laborado, | ||||||
|  |                                 #NIE008 | ||||||
|  |                                 FechaGen=self.fecha_generacion) | ||||||
|  |          | ||||||
|  | @dataclass | ||||||
|  | class Proveedor: | ||||||
|  |     razon_social: str | ||||||
|  |     nit: str | ||||||
|  |     dv: int | ||||||
|  |     software_id: str | ||||||
|  |     software_pin: str | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_attributes('./ProveedorXML', | ||||||
|  |                                 # NIE017 | ||||||
|  |                                 NIT=self.nit, | ||||||
|  |                                 # NIE018 | ||||||
|  |                                 DV=self.dv, | ||||||
|  |                                 # NIE019 | ||||||
|  |                                 SoftwareID=self.software_id, | ||||||
|  |  | ||||||
|  |                                 SoftwareSC=None, | ||||||
|  |                                 # NIE025 | ||||||
|  |                                 RazonSocial=self.razon_social | ||||||
|  |                                 ) | ||||||
|  |  | ||||||
|  |     def post_apply(self, fexml, scopexml, fragment): | ||||||
|  |         cune_xpath = scopexml.xpath_from_root('/InformacionGeneral') | ||||||
|  |         cune = fexml.get_element_attribute(cune_xpath, 'CUNE') | ||||||
|  |          | ||||||
|  |         ambiente = fexml.get_element_attribute(scopexml.xpath_from_root('/InformacionGeneral'), 'Ambiente') | ||||||
|  |         codigo_qr = f"https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey={cune}" | ||||||
|  |  | ||||||
|  |         if InformacionGeneral.AMBIENTE_PRUEBAS.same(ambiente): | ||||||
|  |             codigo_qr = f"https://catalogo-vpfe-hab.dian.gov.co/document/searchqr?documentkey={cune}" | ||||||
|  |         elif ambiente is None: | ||||||
|  |             raise RuntimeError('fail to get InformacionGeneral/@Ambiente') | ||||||
|  |          | ||||||
|  |         scopexml.set_element('./CodigoQR', codigo_qr) | ||||||
|  |         scopexml.set_element('./Novedad', "false")         | ||||||
|  |  | ||||||
|  |         # NIE020 | ||||||
|  |         software_code = self._software_security_code(fexml, scopexml) | ||||||
|  |         fexml.set_attributes(scopexml.xpath_from_root('/ProveedorXML'), SoftwareSC=software_code) | ||||||
|  |  | ||||||
|  |     def _software_security_code(self, fexml, scopexml): | ||||||
|  |          | ||||||
|  |  | ||||||
|  |         # 8.2 | ||||||
|  |         numero = fexml.get_element_attribute(scopexml.xpath_from_root('/NumeroSecuenciaXML'), 'Numero') | ||||||
|  |         if numero is None: | ||||||
|  |             raise RuntimeError('fallo obtener NumeroSequenciaXML/@Numero') | ||||||
|  |          | ||||||
|  |         id_software = self.software_id | ||||||
|  |         software_pin = self.software_pin | ||||||
|  |  | ||||||
|  |         code = "".join([id_software, software_pin, numero]) | ||||||
|  |  | ||||||
|  |         fexml.set_attributes(scopexml.xpath_from_root('/ProveedorXML')) | ||||||
|  |         h = hashlib.sha384() | ||||||
|  |         h.update(code.encode('utf-8')) | ||||||
|  |         return h.hexdigest() | ||||||
|  |      | ||||||
|  | @dataclass | ||||||
|  | class Metadata: | ||||||
|  |     novedad: Novedad | ||||||
|  |     secuencia: NumeroSecuencia | ||||||
|  |     # NIE013, NIE014, NIE015, NIE016 | ||||||
|  |     lugar_generacion: Lugar | ||||||
|  |     proveedor: Proveedor | ||||||
|  |  | ||||||
|  |     def apply(self, novedad, numero_secuencia_xml, lugar_generacion_xml, proveedor_xml): | ||||||
|  |         self.novedad.apply(novedad) | ||||||
|  |         self.secuencia.apply(numero_secuencia_xml) | ||||||
|  |         self.lugar_generacion.apply(lugar_generacion_xml, './LugarGeneracionXML') | ||||||
|  |         self.proveedor.apply(proveedor_xml) | ||||||
|  |  | ||||||
|  |     def post_apply(self, fexml, scopexml, novedad, numero_secuencia_xml, lugar_generacion_xml, proveedor_xml): | ||||||
|  |         self.proveedor.post_apply(fexml, scopexml, proveedor_xml) | ||||||
|  |         self.novedad.post_apply(fexml, scopexml, proveedor_xml)         | ||||||
|  |          | ||||||
|  | @dataclass | ||||||
|  | class PeriodoNomina: | ||||||
|  |     code: str | ||||||
|  |     name: str = '' | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         if self.code not in codelist.PeriodoNomina: | ||||||
|  |             raise ValueError("code [%s] not found" % (self.code)) | ||||||
|  |         self.name = codelist.PeriodoNomina[self.code]['name'] | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class TipoMoneda: | ||||||
|  |     code: str | ||||||
|  |     name: str = '' | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         if self.code not in codelist.TipoMoneda: | ||||||
|  |             raise ValueError("code [%s] not found" % (self.code)) | ||||||
|  |         self.name = codelist.TipoMoneda[self.code]['name'] | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class InformacionGeneral: | ||||||
|  |     @dataclass | ||||||
|  |     class TIPO_AMBIENTE: | ||||||
|  |         valor: str | ||||||
|  |  | ||||||
|  |         @classmethod | ||||||
|  |         def same(cls, value): | ||||||
|  |             return cls.valor == str(value) | ||||||
|  |  | ||||||
|  |     # TABLA 5.1.1 | ||||||
|  |     @dataclass | ||||||
|  |     class AMBIENTE_PRODUCCION(TIPO_AMBIENTE): | ||||||
|  |         valor: str = '1' | ||||||
|  |  | ||||||
|  |         def __str__(self): | ||||||
|  |             self.valor | ||||||
|  |  | ||||||
|  |     @dataclass | ||||||
|  |     class AMBIENTE_PRUEBAS(TIPO_AMBIENTE): | ||||||
|  |         valor: str = '2' | ||||||
|  |  | ||||||
|  |         def __str__(self): | ||||||
|  |             self.valor | ||||||
|  |  | ||||||
|  |     fecha_generacion: typing.Union[str, Fecha] | ||||||
|  |     hora_generacion: str | ||||||
|  |     periodo_nomina: PeriodoNomina | ||||||
|  |     tipo_moneda: TipoMoneda | ||||||
|  |     tipo_ambiente: TIPO_AMBIENTE | ||||||
|  |     software_pin: str | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         self.fecha_generacion = Fecha.cast(self.fecha_generacion) | ||||||
|  |  | ||||||
|  |     def apply(self, fragment, version): | ||||||
|  |         fragment.set_attributes('./InformacionGeneral', | ||||||
|  |                                 # NIE022 | ||||||
|  |                                 Version = version, | ||||||
|  |                                 # NIE023 | ||||||
|  |                                 Ambiente = self.tipo_ambiente.valor, | ||||||
|  |                                 # NIE202 | ||||||
|  |                                 # TABLA 5.5.2 | ||||||
|  |                                 # TODO(bit4bit) solo NominaIndividual | ||||||
|  |                                 TipoXML = '103', | ||||||
|  |                                 # NIE024 | ||||||
|  |                                 CUNE = None, | ||||||
|  |                                 # NIE025 | ||||||
|  |                                 EncripCUNE = 'CUNE-SHA384', | ||||||
|  |                                 # NIE026 | ||||||
|  |                                 FechaGen = self.fecha_generacion, | ||||||
|  |                                 # NIE027 | ||||||
|  |                                 HoraGen = self.hora_generacion, | ||||||
|  |                                 # NIE029 | ||||||
|  |                                 PeriodoNomina = self.periodo_nomina.code, | ||||||
|  |                                 # NIE030 | ||||||
|  |                                 TipoMoneda = self.tipo_moneda.code, | ||||||
|  |                                 TRM = 0 | ||||||
|  |                                 # TODO(bit4bit) resto... | ||||||
|  |                                 # ..... | ||||||
|  |                                 ) | ||||||
|  |  | ||||||
|  |     def post_apply(self, fexml, scopexml, fragment): | ||||||
|  |         # generar cune | ||||||
|  |         # ver 8.1.1.1 | ||||||
|  |         xpaths = [ | ||||||
|  |             scopexml.xpath_from_root('/NumeroSecuenciaXML/@Numero'), | ||||||
|  |             scopexml.xpath_from_root('/InformacionGeneral/@FechaGen'), | ||||||
|  |             scopexml.xpath_from_root('/InformacionGeneral/@HoraGen'), | ||||||
|  |             scopexml.xpath_from_root('/DevengadosTotal'), | ||||||
|  |             scopexml.xpath_from_root('/DeduccionesTotal'), | ||||||
|  |             scopexml.xpath_from_root('/ComprobanteTotal'), | ||||||
|  |             scopexml.xpath_from_root('/Empleador/@NIT'), | ||||||
|  |             scopexml.xpath_from_root('/Trabajador/@NumeroDocumento'), | ||||||
|  |             scopexml.xpath_from_root('/InformacionGeneral/@TipoXML'), | ||||||
|  |             tuple([self.software_pin]), | ||||||
|  |             scopexml.xpath_from_root('/InformacionGeneral/@Ambiente') | ||||||
|  |         ] | ||||||
|  |  | ||||||
|  |         campos = fexml.get_elements_text_or_attributes(xpaths) | ||||||
|  |  | ||||||
|  |         cune = "".join(campos) | ||||||
|  |  | ||||||
|  |         h = hashlib.sha384() | ||||||
|  |         h.update(cune.encode('utf-8')) | ||||||
|  |         cune_hash = h.hexdigest() | ||||||
|  |      | ||||||
|  |         fragment.set_attributes( | ||||||
|  |             './InformacionGeneral', | ||||||
|  |             # NIE024 | ||||||
|  |             CUNE = cune_hash | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | class DianXMLExtensionSigner(fe.DianXMLExtensionSigner): | ||||||
|  |  | ||||||
|  |     def __init__(self, pkcs12_path, passphrase=None, localpolicy=True): | ||||||
|  |         super().__init__(pkcs12_path, passphrase=passphrase, localpolicy=localpolicy) | ||||||
|  |  | ||||||
|  |     def _element_extension_content(self, fachoxml): | ||||||
|  |         return fachoxml.builder.xpath(fachoxml.root, './ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class DIANNominaXML: | ||||||
|  |     def __init__(self, tag_document, xpath_ajuste=None,schemaLocation=None): | ||||||
|  |         self.informacion_general_version = None | ||||||
|  |  | ||||||
|  |         self.tag_document = tag_document | ||||||
|  |         self.fexml = fe.FeXML(tag_document, "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste") | ||||||
|  |  | ||||||
|  |         if schemaLocation is not None: | ||||||
|  |             self.fexml.root.set( | ||||||
|  |                 "SchemaLocation", | ||||||
|  |                 "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd" | ||||||
|  |             ) | ||||||
|  |             self.fexml.root.set("change", schemaLocation) | ||||||
|  |         else: | ||||||
|  |             schemaLocation = "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd" | ||||||
|  |             self.fexml.root.set( | ||||||
|  |                 "SchemaLocation", "") | ||||||
|  |             self.fexml.root.set( | ||||||
|  |                 "change", schemaLocation) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         # self.fexml.root.set( | ||||||
|  |         #    "SchemaLocation", | ||||||
|  |         #    "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd" | ||||||
|  |         #) | ||||||
|  |         # self.fexml.root.set("change", schemaLocation) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         # layout, la dian requiere que los elementos | ||||||
|  |         # esten ordenados segun el anexo tecnico | ||||||
|  |         self.fexml.placeholder_for('./ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent') | ||||||
|  |         self.fexml.placeholder_for('./TipoNota', optional=True) | ||||||
|  |  | ||||||
|  |         self.root_fragment = self.fexml | ||||||
|  |         if xpath_ajuste is not None: | ||||||
|  |             self.root_fragment = self.fexml.fragment(xpath_ajuste) | ||||||
|  |         self.root_fragment.placeholder_for('./ReemplazandoPredecesor', optional=True) | ||||||
|  |         self.root_fragment.placeholder_for('./EliminandoPredecesor', optional=True) | ||||||
|  |         self.root_fragment.placeholder_for('./Novedad', optional=False) | ||||||
|  |         self.root_fragment.placeholder_for('./Periodo') | ||||||
|  |         self.root_fragment.placeholder_for('./NumeroSecuenciaXML') | ||||||
|  |         self.root_fragment.placeholder_for('./LugarGeneracionXML') | ||||||
|  |         self.root_fragment.placeholder_for('./ProveedorXML') | ||||||
|  |         self.root_fragment.placeholder_for('./CodigoQR') | ||||||
|  |         self.root_fragment.placeholder_for('./InformacionGeneral') | ||||||
|  |         self.root_fragment.placeholder_for('./Empleador') | ||||||
|  |         self.root_fragment.placeholder_for('./Trabajador') | ||||||
|  |         self.root_fragment.placeholder_for('./Pago') | ||||||
|  |         self.root_fragment.placeholder_for('./FechasPagos') | ||||||
|  |         self.root_fragment.placeholder_for('./Devengados/Basico') | ||||||
|  |         self.root_fragment.placeholder_for('./Devengados/Transporte', optional=True) | ||||||
|  |  | ||||||
|  |         self.novedad = self.root_fragment.fragment('./Novedad') | ||||||
|  |         self.informacion_general_xml = self.root_fragment.fragment('./InformacionGeneral') | ||||||
|  |         self.periodo_xml = self.root_fragment.fragment('./Periodo') | ||||||
|  |         self.fecha_pagos_xml = self.root_fragment.fragment('./FechasPagos') | ||||||
|  |         self.numero_secuencia_xml = self.root_fragment.fragment('./NumeroSecuenciaXML') | ||||||
|  |         self.lugar_generacion_xml = self.root_fragment.fragment('./LugarGeneracionXML') | ||||||
|  |         self.proveedor_xml = self.root_fragment.fragment('./ProveedorXML') | ||||||
|  |         self.empleador = self.root_fragment.fragment('./Empleador') | ||||||
|  |         self.trabajador = self.root_fragment.fragment('./Trabajador') | ||||||
|  |         self.pago_xml = self.root_fragment.fragment('./Pago') | ||||||
|  |         self.devengados = self.root_fragment.fragment('./Devengados') | ||||||
|  |         self.deducciones = self.root_fragment.fragment('./Deducciones') | ||||||
|  |  | ||||||
|  |         self.informacion_general = None | ||||||
|  |         self.metadata = None | ||||||
|  |  | ||||||
|  |     def asignar_metadata(self, metadata): | ||||||
|  |         if not isinstance(metadata, Metadata): | ||||||
|  |             raise ValueError('se espera tipo Metadata') | ||||||
|  |         self.metadata = metadata | ||||||
|  |         self.metadata.apply(self.novedad, self.numero_secuencia_xml, self.lugar_generacion_xml, self.proveedor_xml) | ||||||
|  |          | ||||||
|  |     def asignar_informacion_general(self, general): | ||||||
|  |         if not isinstance(general, InformacionGeneral): | ||||||
|  |             raise ValueError('se espera tipo InformacionGeneral') | ||||||
|  |         self.informacion_general = general | ||||||
|  |         self.informacion_general.apply(self.informacion_general_xml, self.informacion_general_version) | ||||||
|  |  | ||||||
|  |     def asignar_periodo(self, periodo): | ||||||
|  |         if not isinstance(periodo, Periodo): | ||||||
|  |             raise ValueError('se espera tipo Periodo') | ||||||
|  |  | ||||||
|  |         periodo.apply(self.periodo_xml) | ||||||
|  |  | ||||||
|  |     def asignar_pago(self, pago): | ||||||
|  |         if not isinstance(pago, Pago): | ||||||
|  |             raise ValueError('se espera tipo Pago') | ||||||
|  |         pago.apply(self.pago_xml) | ||||||
|  |  | ||||||
|  |     def asignar_fecha_pago(self, data): | ||||||
|  |         if isinstance(data, str): | ||||||
|  |             fecha = FechaPago(data) | ||||||
|  |         elif isinstance(data, FechaPago): | ||||||
|  |             fecha = data | ||||||
|  |  | ||||||
|  |         fecha.apply(self.fecha_pagos_xml) | ||||||
|  |  | ||||||
|  |     def asignar_empleador(self, empleador): | ||||||
|  |         if not isinstance(empleador, Empleador): | ||||||
|  |             raise ValueError('se espera tipo Empleador') | ||||||
|  |         empleador.apply(self.empleador) | ||||||
|  |  | ||||||
|  |     def asignar_trabajador(self, trabajador): | ||||||
|  |         if not isinstance(trabajador, Trabajador): | ||||||
|  |             raise ValueError('se espera tipo Trabajador') | ||||||
|  |         trabajador.apply(self.trabajador) | ||||||
|  |          | ||||||
|  |     def adicionar_devengado(self, devengado): | ||||||
|  |         if not isinstance(devengado, Devengado): | ||||||
|  |             raise ValueError('se espera tipo Devengado') | ||||||
|  |  | ||||||
|  |         devengado.apply(self.devengados) | ||||||
|  |  | ||||||
|  |     def adicionar_deduccion(self, deduccion): | ||||||
|  |         if not isinstance(deduccion, Deduccion): | ||||||
|  |             raise ValueError('se espera tipo Devengado') | ||||||
|  |  | ||||||
|  |         deduccion.apply(self.deducciones) | ||||||
|  |  | ||||||
|  |     def validate(self): | ||||||
|  |         """ | ||||||
|  |         Valida requisitos segun anexo tecnico | ||||||
|  |         """ | ||||||
|  |         errors = [] | ||||||
|  |  | ||||||
|  |         def check_element(xpath, msg): | ||||||
|  |             if not self.fexml.exist_element(xpath): | ||||||
|  |                 errors.append(DIANNominaIndividualError(msg)) | ||||||
|  |  | ||||||
|  |         def check_attribute(xpath, key, msg): | ||||||
|  |             err = DIANNominaIndividualError(msg) | ||||||
|  |             elem = self.fexml.get_element(xpath) | ||||||
|  |  | ||||||
|  |             if elem is None: | ||||||
|  |                 return errors.append(err) | ||||||
|  |  | ||||||
|  |             if elem.get(key, None) is None: | ||||||
|  |                 return errors.append(err) | ||||||
|  |  | ||||||
|  |         check_attribute( | ||||||
|  |             self.fexml.xpath_from_root('/Periodo'), | ||||||
|  |             'FechaIngreso', | ||||||
|  |             'se requiere Periodo') | ||||||
|  |  | ||||||
|  |         check_element( | ||||||
|  |             self.fexml.xpath_from_root('/Pago'), | ||||||
|  |             'se requiere Pago' | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         check_element( | ||||||
|  |             self.fexml.xpath_from_root('/Devengados/Basico'), | ||||||
|  |             'se requiere DevengadoBasico' | ||||||
|  |         ) | ||||||
|  |          | ||||||
|  |         check_element( | ||||||
|  |             self.fexml.xpath_from_root('/Deducciones/Salud'), | ||||||
|  |             'se requiere DeduccionSalud' | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         check_element( | ||||||
|  |             self.fexml.xpath_from_root('/Deducciones/FondoPension'), | ||||||
|  |             'se requiere DeduccionFondoPension' | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         return errors | ||||||
|  |  | ||||||
|  |     def informacion_general(self): | ||||||
|  |         xpath = self.root_fragment.xpath_from_root('/InformacionGeneral') | ||||||
|  |         return { | ||||||
|  |             'cune': self.fexml.get_element_attribute(cune_xpath, 'CUNE'), | ||||||
|  |             'fecha_generacion': self.fexml.get_element_attribute(xpath, 'FechaGen'), | ||||||
|  |             'numero': self.fexml.get_element_attribute(self.root_fragment('/NumeroSecuenciaXML', 'Numero')) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     def toFachoXML(self): | ||||||
|  |         self._devengados_total() | ||||||
|  |         self._deducciones_total() | ||||||
|  |         self._comprobante_total() | ||||||
|  |  | ||||||
|  |         if self.informacion_general is not None: | ||||||
|  |             #TODO(bit4bit) acoplamiento temporal | ||||||
|  |             # es importante el orden de ejecucion | ||||||
|  |  | ||||||
|  |             self.informacion_general.post_apply(self.fexml, self.root_fragment, self.informacion_general_xml) | ||||||
|  |  | ||||||
|  |         if self.metadata is not None: | ||||||
|  |             self.metadata.post_apply(self.fexml, self.root_fragment, self.novedad, self.numero_secuencia_xml, self.lugar_generacion_xml, self.proveedor_xml) | ||||||
|  |  | ||||||
|  |         return self.fexml | ||||||
|  |  | ||||||
|  |     def _comprobante_total(self): | ||||||
|  |         devengados_total = self.root_fragment.get_element_text_or_attribute('./DevengadosTotal', '0.0') | ||||||
|  |         deducciones_total = self.root_fragment.get_element_text_or_attribute('./DeduccionesTotal', '0.0') | ||||||
|  |  | ||||||
|  |         comprobante_total = Amount(devengados_total) - Amount(deducciones_total) | ||||||
|  |  | ||||||
|  |         self.root_fragment.set_element('./ComprobanteTotal', str(round(comprobante_total, 2))) | ||||||
|  |  | ||||||
|  |     def _deducciones_total(self): | ||||||
|  |         xpaths = [ | ||||||
|  |             self.root_fragment.xpath_from_root('/Deducciones/Salud/@Deduccion'), | ||||||
|  |             self.root_fragment.xpath_from_root('/Deducciones/FondoPension/@Deduccion') | ||||||
|  |         ] | ||||||
|  |         deducciones = map(lambda valor: Amount(valor), | ||||||
|  |                           self._values_of_xpaths(xpaths)) | ||||||
|  |  | ||||||
|  |         deducciones_total = Amount(0.0) | ||||||
|  |          | ||||||
|  |         for deduccion in deducciones: | ||||||
|  |             deducciones_total += deduccion | ||||||
|  |  | ||||||
|  |         self.root_fragment.set_element('./DeduccionesTotal', str(round(deducciones_total, 2))) | ||||||
|  |  | ||||||
|  |     def _devengados_total(self): | ||||||
|  |         xpaths = [ | ||||||
|  |             self.root_fragment.xpath_from_root('/Devengados/Basico/@SueldoTrabajado'), | ||||||
|  |             self.root_fragment.xpath_from_root('/Devengados/Transporte/@AuxilioTransporte'), | ||||||
|  |             self.root_fragment.xpath_from_root('/Devengados/Transporte/@ViaticoManuAlojS'), | ||||||
|  |             self.root_fragment.xpath_from_root('/Devengados/Transporte/@ViaticoManuAlojNS') | ||||||
|  |         ] | ||||||
|  |         devengados = map(lambda valor: Amount(valor), | ||||||
|  |                          self._values_of_xpaths(xpaths)) | ||||||
|  |          | ||||||
|  |         devengados_total = Amount(0.0) | ||||||
|  |         for devengado in devengados: | ||||||
|  |             devengados_total += devengado | ||||||
|  |         self.root_fragment.set_element('./Redondeo', str(round(0,2)))           | ||||||
|  |         self.root_fragment.set_element('./DevengadosTotal', str(round(devengados_total,2))) | ||||||
|  |  | ||||||
|  |     def _values_of_xpaths(self, xpaths): | ||||||
|  |         xpaths_values_of_values = map(lambda val: self.fexml.get_element_text_or_attribute(val, multiple=True), xpaths) | ||||||
|  |         xpaths_values = [] | ||||||
|  |         # toda esta carreta para hacer un aplano de lista | ||||||
|  |         for xpath_values in xpaths_values_of_values: | ||||||
|  |             if xpath_values is None: | ||||||
|  |                 continue | ||||||
|  |  | ||||||
|  |             for xpath_value in xpath_values: | ||||||
|  |                 xpaths_values.append(xpath_value) | ||||||
|  |  | ||||||
|  |         return filter(lambda val: val is not None, xpaths_values) | ||||||
|  |  | ||||||
|  | class DIANNominaIndividual(DIANNominaXML): | ||||||
|  |  | ||||||
|  |     def __init__(self): | ||||||
|  |         super().__init__('NominaIndividual', schemaLocation=schema) | ||||||
|  |         self.informacion_general_version = 'V1.0: Documento Soporte de Pago de Nómina Electrónica' | ||||||
|  |  | ||||||
|  | # TODO(bit4bit) confirmar que no tienen en comun con NominaIndividual | ||||||
|  | class DIANNominaIndividualDeAjuste(DIANNominaXML): | ||||||
|  |     class Reemplazar(DIANNominaXML): | ||||||
|  |         @dataclass | ||||||
|  |         class Predecesor: | ||||||
|  |             numero: str | ||||||
|  |             cune: str | ||||||
|  |             fecha_generacion: str | ||||||
|  |  | ||||||
|  |             def apply(self, fragment): | ||||||
|  |                 fragment.set_element('./TipoNota', '1') | ||||||
|  |                 fragment.set_element('./Reemplazar/ReemplazandoPredecesor', None, | ||||||
|  |                                      # NIAE090 | ||||||
|  |                                      NumeroPred = self.numero, | ||||||
|  |                                      # NIAE191 | ||||||
|  |                                      CUNEPred = self.cune, | ||||||
|  |                                      # NIAE192 | ||||||
|  |                                      FechaGenPred = self.fecha_generacion | ||||||
|  |                                      ) | ||||||
|  |  | ||||||
|  |         def __init__(self): | ||||||
|  |             super().__init__('NominaIndividualDeAjuste', './Reemplazar') | ||||||
|  |             # NIAE214 | ||||||
|  |             # self.root_fragment.set_element('./TipoNota', '1') | ||||||
|  |  | ||||||
|  |         def asignar_predecesor(self, predecesor): | ||||||
|  |             if not isinstance(predecesor, self.Predecesor): | ||||||
|  |                 raise ValueError("se espera tipo Predecesor") | ||||||
|  |             predecesor.apply(self.fexml) | ||||||
|  |  | ||||||
|  |          | ||||||
|  |     class Eliminar(DIANNominaXML): | ||||||
|  |          | ||||||
|  |         @dataclass | ||||||
|  |         class Predecesor: | ||||||
|  |             numero: str | ||||||
|  |             cune: str | ||||||
|  |             fecha_generacion: str | ||||||
|  |  | ||||||
|  |             def apply(self, fragment): | ||||||
|  |                 fragment.set_element('./TipoNota', '2') | ||||||
|  |                 fragment.set_element('./Eliminar/EliminandoPredecesor', None, | ||||||
|  |                                      # NIAE090 | ||||||
|  |                                      NumeroPred = self.numero, | ||||||
|  |                                      # NIAE191 | ||||||
|  |                                      CUNEPred = self.cune, | ||||||
|  |                                      # NIAE192 | ||||||
|  |                                      FechaGenPred = self.fecha_generacion | ||||||
|  |                                      ) | ||||||
|  |  | ||||||
|  |         def __init__(self): | ||||||
|  |             schema = "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd" | ||||||
|  |             super().__init__('NominaIndividualDeAjuste', './Eliminar') | ||||||
|  |  | ||||||
|  |             # self.root_fragment.set_element('./TipoNota', '2') | ||||||
|  |             self.informacion_general_version = "V1.0: Nota de Ajuste de Documento Soporte de Pago de Nómina Electrónica" | ||||||
|  |  | ||||||
|  |         def asignar_predecesor(self, predecesor): | ||||||
|  |             if not isinstance(predecesor, self.Predecesor): | ||||||
|  |                 raise ValueError("se espera tipo Eliminar.Predecesor") | ||||||
|  |             predecesor.apply(self.fexml) | ||||||
|  |  | ||||||
|  |     def __init__(self): | ||||||
|  |         schema = "dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd" | ||||||
|  |         super().__init__('NominaIndividualDeAjuste') | ||||||
							
								
								
									
										4
									
								
								facho/fe/nomina/amount.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								facho/fe/nomina/amount.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | from .. import form | ||||||
|  |  | ||||||
|  | class Amount(form.Amount): | ||||||
|  |     pass | ||||||
							
								
								
									
										3
									
								
								facho/fe/nomina/deduccion/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								facho/fe/nomina/deduccion/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | # contributing | ||||||
|  |  | ||||||
|  | crear nuevo objeto de valor y exportar en **__init__.py** atributo **__all__**. | ||||||
							
								
								
									
										13
									
								
								facho/fe/nomina/deduccion/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								facho/fe/nomina/deduccion/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | # | ||||||
|  | # al crear objetos de valor | ||||||
|  | # se debe exportar en __all__ | ||||||
|  |  | ||||||
|  | from .deduccion import * | ||||||
|  | from .salud import * | ||||||
|  | from .fondo_pension import * | ||||||
|  |  | ||||||
|  | __all__ = [ | ||||||
|  |     'Deduccion', | ||||||
|  |     'DeduccionSalud', | ||||||
|  |     'DeduccionFondoPension' | ||||||
|  | ] | ||||||
							
								
								
									
										2
									
								
								facho/fe/nomina/deduccion/deduccion.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								facho/fe/nomina/deduccion/deduccion.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | class Deduccion: | ||||||
|  |     pass | ||||||
							
								
								
									
										18
									
								
								facho/fe/nomina/deduccion/fondo_pension.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								facho/fe/nomina/deduccion/fondo_pension.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from ..amount import Amount | ||||||
|  | from .deduccion import Deduccion | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DeduccionFondoPension(Deduccion): | ||||||
|  |     porcentaje: Amount | ||||||
|  |     deduccion: Amount | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_element('./FondoPension', None, | ||||||
|  |                              append_ = True, | ||||||
|  |                              # NIE164 | ||||||
|  |                              Porcentaje = str(round(self.porcentaje, 2)), | ||||||
|  |                              #  NIE166 | ||||||
|  |                              Deduccion = self.deduccion | ||||||
|  |                              ) | ||||||
							
								
								
									
										19
									
								
								facho/fe/nomina/deduccion/salud.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								facho/fe/nomina/deduccion/salud.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from ..amount import Amount | ||||||
|  | from .deduccion import Deduccion | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DeduccionSalud(Deduccion): | ||||||
|  |     porcentaje: Amount | ||||||
|  |     deduccion: Amount | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_element('./Salud', None, | ||||||
|  |                              append_ = True, | ||||||
|  |                              # NIE161 | ||||||
|  |                              Porcentaje = str(round(self.porcentaje, 2)), | ||||||
|  |                              #  NIE163 | ||||||
|  |                              Deduccion = self.deduccion | ||||||
|  |                              ) | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								facho/fe/nomina/departamento.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								facho/fe/nomina/departamento.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | from .. import form | ||||||
|  |  | ||||||
|  | class Departamento(form.CountrySubentity): | ||||||
|  |     pass | ||||||
							
								
								
									
										3
									
								
								facho/fe/nomina/devengado/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								facho/fe/nomina/devengado/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | # contributing | ||||||
|  |  | ||||||
|  | crear nuevo objeto de valor y exportar en **__init__.py** atributo **__all__**. | ||||||
							
								
								
									
										19
									
								
								facho/fe/nomina/devengado/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								facho/fe/nomina/devengado/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  |  | ||||||
|  | from .basico import * | ||||||
|  | from .transporte import * | ||||||
|  | from .devengado import * | ||||||
|  | from .horas_extras import * | ||||||
|  |  | ||||||
|  | __all__ = [ | ||||||
|  |     'Devengado', | ||||||
|  |     'DevengadoBasico', | ||||||
|  |     'DevengadoTransporte', | ||||||
|  |     'DevengadoHoraExtra', | ||||||
|  |     'DevengadoHorasExtrasDiarias', | ||||||
|  |     'DevengadoHorasExtrasNocturnas', | ||||||
|  |     'DevengadoHorasRecargoNocturno', | ||||||
|  |     'DevengadoHorasExtrasDiariasDominicalesYFestivos', | ||||||
|  |     'DevengadoHorasRecargoDiariasDominicalesYFestivos', | ||||||
|  |     'DevengadoHorasExtrasNocturnasDominicalesYFestivos', | ||||||
|  |     'DevengadoHorasRecargoNocturnoDominicalesYFestivos' | ||||||
|  | ] | ||||||
							
								
								
									
										20
									
								
								facho/fe/nomina/devengado/basico.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								facho/fe/nomina/devengado/basico.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from ..amount import Amount | ||||||
|  | from .devengado import Devengado | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoBasico(Devengado): | ||||||
|  |     dias_trabajados: int | ||||||
|  |     sueldo_trabajado: Amount | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.find_or_create_element('./Basico') | ||||||
|  |          | ||||||
|  |         fragment.set_attributes('/Basico', | ||||||
|  |                                 # NIE069 | ||||||
|  |                                 DiasTrabajados = str(self.dias_trabajados), | ||||||
|  |                                 # NIE070 | ||||||
|  |                                 SueldoTrabajado = round(self.sueldo_trabajado, 2) | ||||||
|  |                                 ) | ||||||
							
								
								
									
										2
									
								
								facho/fe/nomina/devengado/devengado.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								facho/fe/nomina/devengado/devengado.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | class Devengado: | ||||||
|  |     pass | ||||||
							
								
								
									
										93
									
								
								facho/fe/nomina/devengado/horas_extras.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								facho/fe/nomina/devengado/horas_extras.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  | from typing import List | ||||||
|  |  | ||||||
|  | from ..amount import Amount | ||||||
|  | from .devengado import Devengado | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoHoraExtra: | ||||||
|  |     hora_inicio: str | ||||||
|  |     hora_fin: str | ||||||
|  |     cantidad: int | ||||||
|  |     porcentaje: Amount | ||||||
|  |     pago: Amount | ||||||
|  |  | ||||||
|  |     def apply(self, child_path, fragment): | ||||||
|  |         fragment.set_element(child_path, None, | ||||||
|  |                              append_=True, | ||||||
|  |                              # NIE074 | ||||||
|  |                              HoraInicio=self.hora_inicio, | ||||||
|  |                              # NIE075 | ||||||
|  |                              HoraFin=self.hora_fin, | ||||||
|  |                              # NIE076 | ||||||
|  |                              Cantidad=self.cantidad, | ||||||
|  |                              # NIE077 | ||||||
|  |                              Porcentaje=str(round(self.porcentaje, 2)), | ||||||
|  |                              # NIE078 | ||||||
|  |                              Pago=str(round(self.pago, 2))) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoHorasExtrasDiarias(Devengado): | ||||||
|  |     horas_extras: List[DevengadoHoraExtra] | ||||||
|  |      | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         hora_extra_xml = fragment.fragment('./HEDs') | ||||||
|  |         for hora_extra in self.horas_extras: | ||||||
|  |             hora_extra.apply('./HED', hora_extra_xml) | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoHorasExtrasNocturnas(Devengado): | ||||||
|  |     horas_extras: List[DevengadoHoraExtra] | ||||||
|  |      | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         hora_extra_xml = fragment.fragment('./HENs') | ||||||
|  |         for hora_extra in self.horas_extras: | ||||||
|  |             hora_extra.apply('./HEN', hora_extra_xml) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoHorasRecargoNocturno(Devengado): | ||||||
|  |     horas_extras: List[DevengadoHoraExtra] | ||||||
|  |      | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         hora_extra_xml = fragment.fragment('./HRNs') | ||||||
|  |         for hora_extra in self.horas_extras: | ||||||
|  |             hora_extra.apply('./HRN', hora_extra_xml) | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoHorasExtrasDiariasDominicalesYFestivos(Devengado): | ||||||
|  |     horas_extras: List[DevengadoHoraExtra] | ||||||
|  |      | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         hora_extra_xml = fragment.fragment('./HEDDFs') | ||||||
|  |         for hora_extra in self.horas_extras: | ||||||
|  |             hora_extra.apply('./HEDDF', hora_extra_xml) | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoHorasRecargoDiariasDominicalesYFestivos(Devengado): | ||||||
|  |     horas_extras: List[DevengadoHoraExtra] | ||||||
|  |      | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         hora_extra_xml = fragment.fragment('./HRDDFs') | ||||||
|  |         for hora_extra in self.horas_extras: | ||||||
|  |             hora_extra.apply('./HRDDF', hora_extra_xml) | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoHorasExtrasNocturnasDominicalesYFestivos(Devengado): | ||||||
|  |     horas_extras: List[DevengadoHoraExtra] | ||||||
|  |      | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         hora_extra_xml = fragment.fragment('./HENDFs') | ||||||
|  |         for hora_extra in self.horas_extras: | ||||||
|  |             hora_extra.apply('./HENDF', hora_extra_xml) | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoHorasRecargoNocturnoDominicalesYFestivos(Devengado): | ||||||
|  |     horas_extras: List[DevengadoHoraExtra] | ||||||
|  |      | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         hora_extra_xml = fragment.fragment('./HRNDFs') | ||||||
|  |         for hora_extra in self.horas_extras: | ||||||
|  |             hora_extra.apply('./HRNDF', hora_extra_xml) | ||||||
							
								
								
									
										21
									
								
								facho/fe/nomina/devengado/transporte.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								facho/fe/nomina/devengado/transporte.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from ..amount import Amount | ||||||
|  | from .devengado import Devengado | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class DevengadoTransporte(Devengado): | ||||||
|  |     auxilio_transporte: Amount = None | ||||||
|  |     viatico_manutencion: Amount = None | ||||||
|  |     viatico_manutencion_no_salarial: Amount = None | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_element('./Transporte', None, | ||||||
|  |                              append_ = True, | ||||||
|  |                              # NIE071 | ||||||
|  |                              AuxilioTransporte = self.auxilio_transporte, | ||||||
|  |                              # NIE072 | ||||||
|  |                              ViaticoManuAlojS = self.viatico_manutencion, | ||||||
|  |                              # NIE073 | ||||||
|  |                              ViaticoManuAlojNS = self.viatico_manutencion_no_salarial | ||||||
|  |                              ) | ||||||
							
								
								
									
										35
									
								
								facho/fe/nomina/empleador/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								facho/fe/nomina/empleador/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from ..pais import Pais | ||||||
|  | from ..departamento import Departamento | ||||||
|  | from ..municipio import Municipio | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class Empleador: | ||||||
|  |     razon_social: str | ||||||
|  |     nit: str | ||||||
|  |     dv: str | ||||||
|  |     pais: Pais | ||||||
|  |     departamento: Departamento | ||||||
|  |     municipio: Municipio | ||||||
|  |     direccion: str | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_attributes('./Empleador', | ||||||
|  |                                 # NIE033 | ||||||
|  |                                 NIT = self.nit, | ||||||
|  |                                 # NIE034 | ||||||
|  |                                 DV = self.dv, | ||||||
|  |                                 # NIE035 | ||||||
|  |                                 Pais = self.pais.code, | ||||||
|  |                                 # NIE036 | ||||||
|  |                                 DepartamentoEstado = self.departamento.code, | ||||||
|  |                                 # NIE037 | ||||||
|  |                                 MunicipioCiudad = self.municipio.code, | ||||||
|  |                                 # NIE038 | ||||||
|  |                                 Direccion = self.direccion, | ||||||
|  |  | ||||||
|  |                                 RazonSocial=self.razon_social | ||||||
|  |                                 ) | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								facho/fe/nomina/exception.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								facho/fe/nomina/exception.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | class DIANNominaIndividualError(Exception): | ||||||
|  |     pass | ||||||
							
								
								
									
										155
									
								
								facho/fe/nomina/hablitacion.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								facho/fe/nomina/hablitacion.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  | import datetime | ||||||
|  |  | ||||||
|  | from facho import fe | ||||||
|  |  | ||||||
|  | class Habilitacion: | ||||||
|  |  | ||||||
|  |     @dataclass | ||||||
|  |     class Metadata: | ||||||
|  |         software_pin: str | ||||||
|  |         software_id: str | ||||||
|  |         nit: str | ||||||
|  |         dv: str | ||||||
|  |  | ||||||
|  |     def __init__(self, metadata): | ||||||
|  |         self.metadata = metadata | ||||||
|  |  | ||||||
|  |     def generar(self, zipname, fecha): | ||||||
|  |         nominas = [] | ||||||
|  |         dianzip = fe.DianZIP(open(zipname, 'w')) | ||||||
|  |  | ||||||
|  |         fechabase = datetime.datetime.now() | ||||||
|  |         consecutivo = 0 | ||||||
|  |         for _ in range(1, 11): | ||||||
|  |             consecutivo += 1 | ||||||
|  |             fechabase += datetime.timedelta(days=1) | ||||||
|  |             nomina = self._crear_nomina_individual() | ||||||
|  |  | ||||||
|  |             # pag 96 | ||||||
|  |             nombre = "nie%010d%s%08x.xml" % (int(self.nit), fecha.strftime('%s'), consecutivo) | ||||||
|  |          | ||||||
|  |     def _crear_nomina_individual_reemplazar(self, nomina, fechabase): | ||||||
|  |         metadata = self.metadata | ||||||
|  |  | ||||||
|  |         fecha = fechabase.strftime('%Y-%m-%d') | ||||||
|  |  | ||||||
|  |         nomina_ajuste = fe.nomina.DIANNominaIndividualDeAjuste.Reemplazar() | ||||||
|  |         self._poblar_nomina(nomina_ajuste, metadata, fecha, prefijo='R') | ||||||
|  |         informacion_general = nomina.informacion_general() | ||||||
|  |          | ||||||
|  |          | ||||||
|  |     def _poblar_nomina(self, nomina, metadata, fecha, prefijo='N', consecutivo='0001'): | ||||||
|  |         nomina.asignar_fecha_pago(fecha) | ||||||
|  |  | ||||||
|  |         nomina.asignar_metadata(fe.nomina.Metadata( | ||||||
|  |             secuencia=fe.nomina.NumeroSecuencia( | ||||||
|  |                 prefijo=prefijo, | ||||||
|  |                 consecutivo=consecutivo | ||||||
|  |             ), | ||||||
|  |             lugar_generacion=fe.nomina.Lugar( | ||||||
|  |                 pais = fe.nomina.Pais( | ||||||
|  |                     code = 'CO' | ||||||
|  |                 ), | ||||||
|  |                 departamento = fe.nomina.Departamento( | ||||||
|  |                     code = '05' | ||||||
|  |                 ), | ||||||
|  |                 municipio = fe.nomina.Municipio( | ||||||
|  |                     code = '05001' | ||||||
|  |                 ), | ||||||
|  |             ), | ||||||
|  |             proveedor=fe.nomina.Proveedor( | ||||||
|  |                 nit=metadata.nit, | ||||||
|  |                 dv=metadata.dv, | ||||||
|  |                 software_id=metadata.software_id, | ||||||
|  |                 software_pin=metadata.software_pin | ||||||
|  |             ) | ||||||
|  |         )) | ||||||
|  |  | ||||||
|  |         nomina.asignar_periodo(fe.nomina.Periodo( | ||||||
|  |             fecha_ingreso=fecha, | ||||||
|  |             fecha_liquidacion_inicio=fecha, | ||||||
|  |             fecha_liquidacion_fin=fecha, | ||||||
|  |             fecha_generacion=fecha, | ||||||
|  |         )) | ||||||
|  |          | ||||||
|  |         nomina.asignar_informacion_general(fe.nomina.InformacionGeneral( | ||||||
|  |             fecha_generacion = fecha, | ||||||
|  |             hora_generacion = '20:09:00-05:00', | ||||||
|  |             tipo_ambiente = fe.nomina.InformacionGeneral.AMBIENTE_PRUEBAS, | ||||||
|  |             software_pin = metadata.software_pin, | ||||||
|  |             periodo_nomina = fe.nomina.PeriodoNomina(code='1'), | ||||||
|  |             tipo_moneda = fe.nomina.TipoMoneda(code='COP') | ||||||
|  |         )) | ||||||
|  |  | ||||||
|  |         nomina.asignar_pago(fe.nomina.Pago( | ||||||
|  |             forma=fe.nomina.FormaPago( | ||||||
|  |                 code='1', | ||||||
|  |             ), | ||||||
|  |             metodo=fe.nomina.MetodoPago( | ||||||
|  |                 code='10' | ||||||
|  |             ) | ||||||
|  |         )) | ||||||
|  |         nomina.asignar_empleador(fe.nomina.Empleador( | ||||||
|  |             nit = metadata.nit, | ||||||
|  |             dv = '0', | ||||||
|  |             pais = fe.nomina.Pais( | ||||||
|  |                 code = 'CO' | ||||||
|  |             ), | ||||||
|  |             departamento = fe.nomina.Departamento( | ||||||
|  |                 code = '05' | ||||||
|  |             ), | ||||||
|  |             municipio = fe.nomina.Municipio( | ||||||
|  |                 code = '05001' | ||||||
|  |             ), | ||||||
|  |             direccion = 'calle etrivial' | ||||||
|  |         )) | ||||||
|  |  | ||||||
|  |         nomina.asignar_trabajador(fe.nomina.Trabajador( | ||||||
|  |             tipo_contrato = fe.nomina.TipoContrato( | ||||||
|  |                 code = '1' | ||||||
|  |             ), | ||||||
|  |             alto_riesgo = False, | ||||||
|  |             tipo_documento = fe.nomina.TipoDocumento( | ||||||
|  |                 code = '11' | ||||||
|  |             ), | ||||||
|  |             primer_apellido = 'gnu', | ||||||
|  |             segundo_apellido = 'emacs', | ||||||
|  |             primer_nombre = 'facho', | ||||||
|  |             lugar_trabajo = fe.nomina.LugarTrabajo( | ||||||
|  |                 pais = fe.nomina.Pais(code='CO'), | ||||||
|  |                 departamento = fe.nomina.Departamento(code='05'), | ||||||
|  |                 municipio = fe.nomina.Municipio(code='05001'), | ||||||
|  |                 direccion = 'calle facho' | ||||||
|  |             ), | ||||||
|  |             numero_documento = metadata.nit, | ||||||
|  |             tipo = fe.nomina.TipoTrabajador( | ||||||
|  |                 code = '01' | ||||||
|  |             ), | ||||||
|  |             salario_integral = True, | ||||||
|  |             sueldo = fe.nomina.Amount(1_500_000) | ||||||
|  |         )) | ||||||
|  |          | ||||||
|  |         nomina.adicionar_devengado(fe.nomina.DevengadoBasico( | ||||||
|  |             dias_trabajados = 60, | ||||||
|  |             sueldo_trabajado = fe.nomina.Amount(3_500_000) | ||||||
|  |         )) | ||||||
|  |  | ||||||
|  |         nomina.adicionar_deduccion(fe.nomina.DeduccionSalud( | ||||||
|  |             porcentaje = fe.nomina.Amount(19), | ||||||
|  |             deduccion = fe.nomina.Amount(1_000_000) | ||||||
|  |         )) | ||||||
|  |  | ||||||
|  |         nomina.adicionar_deduccion(fe.nomina.DeduccionFondoPension( | ||||||
|  |             porcentaje=fe.nomina.Amount(1), | ||||||
|  |             deduccion=fe.nomina.Amount(10) | ||||||
|  |         )) | ||||||
|  |  | ||||||
|  |     def _crear_nomina_individual(self, fechabase): | ||||||
|  |         metadata = self.metadata | ||||||
|  |  | ||||||
|  |         fecha = fechabase.strftime('%Y-%m-%d') | ||||||
|  |  | ||||||
|  |         nomina = fe.nomina.DIANNominaIndividual() | ||||||
|  |         self._poblar_nomina(nomina, metadata, fecha) | ||||||
|  |                  | ||||||
							
								
								
									
										25
									
								
								facho/fe/nomina/lugar.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								facho/fe/nomina/lugar.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from .pais import Pais | ||||||
|  | from .departamento import Departamento | ||||||
|  | from .municipio import Municipio | ||||||
|  | from facho.fe.data.dian import codelist | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class Lugar: | ||||||
|  |     pais: Pais | ||||||
|  |     departamento: Departamento | ||||||
|  |     municipio: Municipio | ||||||
|  |     idioma: str = 'es' | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         if self.idioma not in codelist.IdiomaISO6391: | ||||||
|  |             raise ValueError("idioma [%s] not found" % (self.code)) | ||||||
|  |         codelist.IdiomaISO6391[self.idioma]['iso-639-1'] | ||||||
|  |  | ||||||
|  |     def apply(self, fragment, root): | ||||||
|  |         fragment.set_attributes(root, | ||||||
|  |                                 Pais=self.pais.code, | ||||||
|  |                                 DepartamentoEstado=self.departamento.code, | ||||||
|  |                                 MunicipioCiudad=self.municipio.code, | ||||||
|  |                                 Idioma=self.idioma) | ||||||
							
								
								
									
										5
									
								
								facho/fe/nomina/municipio.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								facho/fe/nomina/municipio.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | from .. import form | ||||||
|  |  | ||||||
|  | class Municipio(form.City): | ||||||
|  |     pass | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								facho/fe/nomina/pago/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								facho/fe/nomina/pago/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from .forma_pago import FormaPago | ||||||
|  | from .metodo_pago import MetodoPago | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class Pago: | ||||||
|  |     forma: FormaPago | ||||||
|  |     metodo: MetodoPago | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_attributes('./Pago', | ||||||
|  |                                 # NIE064 | ||||||
|  |                                 Forma = self.forma.code, | ||||||
|  |                                 # NIE065 | ||||||
|  |                                 Metodo = self.metodo.code) | ||||||
							
								
								
									
										13
									
								
								facho/fe/nomina/pago/forma_pago.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								facho/fe/nomina/pago/forma_pago.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from facho.fe.data.dian import codelist | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class FormaPago: | ||||||
|  |     code: str | ||||||
|  |     name: str = '' | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         if self.code not in codelist.FormasPago: | ||||||
|  |             raise ValueError("code [%s] not found" % (self.code)) | ||||||
|  |         self.name = codelist.FormasPago[self.code]['name'] | ||||||
							
								
								
									
										14
									
								
								facho/fe/nomina/pago/metodo_pago.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								facho/fe/nomina/pago/metodo_pago.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from facho.fe.data.dian import codelist | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class MetodoPago: | ||||||
|  |     code: str | ||||||
|  |     name: str = '' | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         if self.code not in codelist.MediosPago: | ||||||
|  |             raise ValueError("code [%s] not found" % (self.code)) | ||||||
|  |         self.name = codelist.MediosPago[self.code]['name'] | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								facho/fe/nomina/pais.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								facho/fe/nomina/pais.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | from .. import form | ||||||
|  |  | ||||||
|  | class Pais(form.Country): | ||||||
|  |     pass | ||||||
							
								
								
									
										73
									
								
								facho/fe/nomina/trabajador/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								facho/fe/nomina/trabajador/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from ..amount import Amount | ||||||
|  |  | ||||||
|  | from .tipo_contrato import * | ||||||
|  | from .tipo_documento import * | ||||||
|  | from .lugar_trabajo import * | ||||||
|  | from .tipo_trabajador import * | ||||||
|  | from .sub_tipo_trabajador import * | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class Trabajador: | ||||||
|  |     tipo_contrato: TipoContrato | ||||||
|  |     tipo_documento: TipoDocumento | ||||||
|  |     numero_documento: str | ||||||
|  |  | ||||||
|  |     primer_apellido: str | ||||||
|  |     segundo_apellido: str | ||||||
|  |     primer_nombre: str | ||||||
|  |  | ||||||
|  |     lugar_trabajo: LugarTrabajo | ||||||
|  |     alto_riesgo: bool | ||||||
|  |     salario_integral: bool | ||||||
|  |     sueldo: Amount | ||||||
|  |  | ||||||
|  |     tipo: TipoTrabajador | ||||||
|  |  | ||||||
|  |     codigo_trabajador: str = None | ||||||
|  |     otros_nombres: str = None | ||||||
|  |     sub_tipo: SubTipoTrabajador = SubTipoTrabajador(code='00') | ||||||
|  |  | ||||||
|  |     def apply(self, fragment): | ||||||
|  |         fragment.set_attributes('./Trabajador', | ||||||
|  |                                 # NIE041 | ||||||
|  |                                 TipoTrabajador = self.tipo.code, | ||||||
|  |                                 # NIE042 | ||||||
|  |                                 SubTipoTrabajador = self.sub_tipo.code, | ||||||
|  |                                 # NIE043 | ||||||
|  |                                 AltoRiesgoPension = str(self.alto_riesgo).lower(), | ||||||
|  |                                 # NIE044 | ||||||
|  |                                 TipoDocumento = self.tipo_documento.code, | ||||||
|  |                                 # NIE045 | ||||||
|  |                                 NumeroDocumento = self.numero_documento, | ||||||
|  |                                 # NIE046 | ||||||
|  |                                 PrimerApellido = self.primer_apellido, | ||||||
|  |                                 # NIE047 | ||||||
|  |                                 SegundoApellido = self.segundo_apellido, | ||||||
|  |                                 # NIE048 | ||||||
|  |                                 PrimerNombre = self.primer_nombre, | ||||||
|  |                                 # NIE049 | ||||||
|  |                                 OtrosNombres = self.otros_nombres, | ||||||
|  |                                 # NIE050 | ||||||
|  |                                 LugarTrabajoPais = self.lugar_trabajo.pais.code, | ||||||
|  |  | ||||||
|  |                                 # NIE051 | ||||||
|  |                                 LugarTrabajoDepartamentoEstado = self.lugar_trabajo.departamento.code, | ||||||
|  |  | ||||||
|  |                                 # NIE052 | ||||||
|  |                                 LugarTrabajoMunicipioCiudad = self.lugar_trabajo.municipio.code, | ||||||
|  |  | ||||||
|  |                                 # NIE053 | ||||||
|  |                                 LugarTrabajoDireccion = self.lugar_trabajo.direccion, | ||||||
|  |                                 # NIE056 | ||||||
|  |                                 SalarioIntegral = str(self.salario_integral).lower(), | ||||||
|  |                                 # NIE061 | ||||||
|  |                                 TipoContrato = self.tipo_contrato.code, | ||||||
|  |                                 # NIE062 | ||||||
|  |                                 Sueldo = str(self.sueldo), | ||||||
|  |                                 # NIE063 | ||||||
|  |                                 CodigoTrabajador = self.codigo_trabajador | ||||||
|  |                                 ) | ||||||
							
								
								
									
										13
									
								
								facho/fe/nomina/trabajador/lugar_trabajo.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								facho/fe/nomina/trabajador/lugar_trabajo.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from . import * | ||||||
|  | from ..pais import Pais | ||||||
|  | from ..departamento import Departamento | ||||||
|  | from ..municipio import Municipio | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class LugarTrabajo: | ||||||
|  |     pais: Pais | ||||||
|  |     departamento: Departamento | ||||||
|  |     municipio: Municipio | ||||||
|  |     direccion: str | ||||||
							
								
								
									
										13
									
								
								facho/fe/nomina/trabajador/sub_tipo_trabajador.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								facho/fe/nomina/trabajador/sub_tipo_trabajador.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from facho.fe.data.dian import codelist | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class SubTipoTrabajador: | ||||||
|  |     code: str | ||||||
|  |     name: str = '' | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         if self.code not in codelist.SubTipoTrabajador: | ||||||
|  |             raise ValueError("code [%s] not found" % (self.code)) | ||||||
|  |         self.name = codelist.SubTipoTrabajador[self.code]['name'] | ||||||
							
								
								
									
										15
									
								
								facho/fe/nomina/trabajador/tipo_contrato.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								facho/fe/nomina/trabajador/tipo_contrato.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | from dataclasses import dataclass | ||||||
|  |  | ||||||
|  | from facho.fe.data.dian import codelist | ||||||
|  |  | ||||||
|  | @dataclass | ||||||
|  | class TipoContrato: | ||||||
|  |     code: str | ||||||
|  |     name: str = '' | ||||||
|  |  | ||||||
|  |     def __post_init__(self): | ||||||
|  |         if self.code not in codelist.TipoContrato: | ||||||
|  |             raise ValueError("code [%s] not found" % (self.code)) | ||||||
|  |         self.name = codelist.TipoContrato[self.code]['name'] | ||||||
|  |  | ||||||
|  |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user