Un wrapper para el eDNI (eDNI en Fedora 12)

 

 

Por Juan Antonio Martínez (Jonsito)

A raíz de un artículo en BarraPunto, y como reto personal, me propuse hacer funcionar el paquete que la DGP ofrece para Fedora 10 en mi Fedora 12. No sólo eso: además el procedimiento debía ser adaptable a cualquier distribución.

Los lectores de BarraPunto se han encontrado estos días con un interesante artículo [pdf] sobre ingeniería inversa a nuestro querido, amado y nunca bien ponderado DNI electrónico.

En él se puede ver que, a pesar de los denodados esfuerzos de nuestra Dirección General de la Policía, la publicación de un driver libre para el DNI electrónico es cuestión de (muy poco) tiempo...

Entretanto no tenemos más remedio que seguir tirando de los tristes drivers que nos ofrece la página web oficial, y donde vemos que nuestras posibilidades están más que reducidas: en lugar de un driver "universal", la DGP nos ofrece unas pocas -y anticuadas- instalaciones tipo. En cuanto nuestra distribución favorita actualice el paquete OpenSC, el dni dejará de funcionar.

...¿o no?

He aquí la criatura: un wrapper para la biblioteca propietaria libopensc-dnie.so

Una observación: me parece muy triste que sea la Comunidad Linux la que tenga que resolver a la administración sus meteduras de pata. Primero fue la Tarjeta Ceres; despues el DNI electrónico. Estoy seguro que hay técnicos altamente competentes y cualificados en la administración, y que debe ser para ellos una pena que por intereses políticos y comerciales, o conceptos malentendidos de seguridad informática, no hagan realmente bandera del acceso universal a la administración.

Bueno, basta de política; vamos allá:

El siguiente proceso indica los pasos necesarios para instalar el soporte de DNI electrónico en Fedora 12. El procedimiento descrito es fácilmente exportable a otras distribuciones Linux que utilicen el paquete OpenSC-0.11.x

La web oficial del dni electrónico sólo da soporte a determinadas versiones de OpenSC. Debido a la política de actualizaciones de las distribuciones, los paquetes precompilados sólo funcionan en algunas distros. Para más desgracia, las actualizaciones del paquete OpenSC dentro de la misma distribución, hacen que el módulo opensc-dnie ofrecido por la DGP deje de funcionar al cambiar OpenSC de versión.

El problema se debe a que los diseñadores de OpenSC, para penalizar el uso de bibliotecas propietarias, escribieron en el código que realiza la carga de módulos dinámicos una rutina de comprobación del número de versión del módulo. Esto obliga a que por cada nueva revisión de OpenSC, todos los módulos dinámicos deban ser recompilados. Si bien la licencia LGPL permite el enlace dinámico con módulos propietarios, el sentir de los desarrolladores es que la "seguridad por oscuridad" es contraproducente tratándose de tarjetas criptográficas, y no desean dar facilidades al desarrollo de drivers propietarios.

La filosofia es pues permitir enlace dinámico, pero forzar a los autores a liberar sus fuentes, o bien a publicar -y mantener- wrappers libres.

De hecho, los desarrolladores actuales de OpenSC considerarán que la carga de drivers dinámicos a partir de la version 0.12 es una "obsolete feature".

Lo aquí escrito funciona pues con las versiones OpenSC-0.11.x, pero no se garantiza que siga funcionando más allá de OpenSC-0.12

En la serie 0.11.x, los módulos deben implementar y exportar la funcion char *sc_driver_version(), que retorna el número de versión contra el que fue enlazado el modulo. En el caso del paquete que la DGP ofrece para fedora 10, sc_driver_version retorna "0.11.7" con lo que sólo puede -en teoría- funcionar en OpenSC-0.11.7. De este modo, cuando se intenta ejecutar el driver de la DGP en Fedora 12 se obtiene un bonito mensaje "ctx.c:load_dynamic_driver: Invalid module version", y se aborta la carga del módulo:

user$ pkcs15-tool --list-public-keys
[pkcs15-tool] ctx.c:367:load_dynamic_driver: dynamic library '/usr/lib/libopensc-dnie.so.1.0.3': invalid module version
[pkcs15-tool] ctx.c:467:load_card_drivers: Unable to load 'dnie'.

 

En el momento de escribir estas líneas, Fedora 12 utiliza la versión OpenSC-0.11.11, con lo que debemos "engañar" a OpenSC para que se crea que el módulo de DNIe corresponde a dicha versión.

Para engañarlo, debemos conseguir que la función sc_driver_version devuelva el string que nosotros queramos, en lugar del que tiene pre-compilado. Para ello hay que hacer lo siguiente:

- Eliminar (o en nuestro caso cambiar el nombre) la referencia a sc_driver_version en la biblioteca propietaria.

- Crear una nueva biblioteca que incluya la función con el string de retorno que nosotros queremos.

- Decirle a opensc que utilice la nueva biblioteca.

Antes de empezar se asume que OpenSC y pcsc-lite están correctamente instalados y configurados. Remitimos al consabido RTFM...

El procedimiento que he seguido es el siguiente:

 

1- Descargar e Instalar rpm de Fedora 10

La Dirección General de la Policía distribuye un fichero tar, que contiene dos rpm's: opensc-0.11.7 y opensc-dnie-1.4.6.

1.1- Ignoramos el primero e instalamos el segundo:

root# rpm -v -i opensc-dnie-1.4.6-2.fc10.i386.rpm

 

1.2- Se abre una ventana del navegador, que indica que busquemos en el menú de aplicaciones el instalador del dnie en Firefox. Pulsamos en dicho menú, y aparece una ventana con instrucciones extras, que nosotros obedientemente _DES_obedecemos :-) (son instrucciones para cargar y activar el certificado de la DGP, pero Firefox es muy listo y lo hace automáticamente)

 

2- Preparación

Una vez instalado el paquete, vamos a parchear. Necesitaremos la utilidad objcopy (paquete binutils) y por supuesto gcc y su familia.

2.1- creamos directorio de trabajo y copiamos archivos:

user$ mkdir /tmp/dnie
user$ cd /tmp/dnie

 

2.1- Copiamos la biblioteca original al espacio de trabajo:

user$ cp /usr/lib/libopensc-dnie.so.1.0.3 libopensc-dnie.so.1.0.3.orig

 

3- Creación del wrapper

3.1- Editamos el parche. En función de la distribución, ajustaremos el valor del string a la versión de OpenSC que tengamos instalada...

user$ vi patch.c
char *patched_driver_version="0.11.11"; char * sc_driver_version() { return patched_driver_version; }

 

NOTA: para hacer las cosas bien, deberíamos tener instalado opensc-devel, y preguntar a
opensc su número de versión... se deja como tarea al lector...

3.2- Compilamos, generando un .o "relocatabl":

user$ gcc -fpic -g -c -Wall patch.c

 

4- Generamos las bibliotecas necesarias

4.1- Parcheamos la librería original, cambiando nombre de la función sc_driver_versión:

user$ objcopy --redefine-sym sc_driver_version=orig_sc_driver_version libopensc-dnie.so.1.0.3.orig libopensc-dnie.so.1.0.3
user$ chmod +x libopensc-dnie.so.1.0.3

 

4.2- Creamos una nueva dll con el fichero que hemos compilado:

user$ gcc -shared -Wl,-soname,libwrapper-dnie.so libopensc-dnie.so.1.0.3 patch.o -o libwrapper-dnie.so.1.0.0

 

4.3- En estos momentos tenemos dos dll's:

- La original parcheada, en la que se ha renombrado la función "sc_driver_version" por "orig_sc_driver_version".

- La que hemos creado, que define "sc_driver_version" y enlaza con la anterior.

 

5- Instalación y configuración

5.1- Copiamos las nueva dll's a /usr/lib y actualizamos el cache del dynloader
(para esto se necesita ser root)

user$ su
root# cp libwrapper-dnie.so.1.0.0 libopensc-dnie.so.1.0.3 /usr/lib
root# ldconfig 

 

5.2- Editar /etc/opensc.conf, cambiando la biblioteca a utilizar:

root# vi /etc/opensc.conf

Donde pone:

module = /usr/lib/libopensc-dnie.so;

Debe poner:

# module = /usr/lib/libopensc-dnie.so;
module = /usr/lib/libwrapper-dnie.so;

root# exit

 

6- Prueba

Volvemos a ser usuario normal. Insertamos el dni en lector y probamos que no hemos metido la pata:

user$ pkcs15-tool --list-public-keys
Public RSA Key [KpuAutenticacion]
	Com. Flags  : 3
	Usage       : [0xC0], verify, verifyRecover
	Access Flags: [0x12], extract, local
	ModLength   : 2048
	Key ref     : 1
	Native      : yes
	Path        : 3f003f110101
	Auth ID     : 
	ID          : 4138363639413238303730354638453230303930353235313033353232

Public RSA Key [KpuFirmaDigital]
	Com. Flags  : 3
	Usage       : [0x2C0], verify, verifyRecover, nonRepudiation
	Access Flags: [0x12], extract, local
	ModLength   : 2048
	Key ref     : 2
	Native      : yes
	Path        : 3f003f110102
	Auth ID     : 
	ID          : 4638363639413238303730354638453230303930353235313033353232

 

Y esto es todo, amigos: Ya tengo mi DNI electrónico funcionando con Fedora 12

Un último apunte: en la página web del DNI electrónico, podemos ver que opensc-dnie-1.4.6 no es la versión más moderna, sino que está disponible (aunque para debian) la versión 1.4.7. Antes de que el lector lo intente, desgraciadamente tengo que comentar que esta versión está "strippeada", con lo que el parcheo con objcopy no funciona (no encuentra el símbolo en la tabla).

Que vuesas mercedes lo disfruten con salud

Juan Antonio Martinez jonsito _en_ terra _dot_ es

Copyright 2010 by Juan Antonio Martinez. Se permite la libre copia, modificación y distribución por cualquier medio, siempre que se indique el autor y se indique un enlace al artículo original publicado en Kriptópolis.

Comentarios

Selecciona arriba tu forma preferida de visualizar los comentarios y pulsa el botón para guardar tu elección para próximas visitas (sólo si eres usuario registrado).
jonsito's picture

La gente de OpenSC está un "pelin" mosqueada...


On Mar 23, 2010, at 11:47 , xxxxx at terra.es wrote:
> > On Mar 20, 2010, at 21:11 , xxxxx wrote:
> > Maybe you can help us find the source instead (or help communicating with the agency distributing the software if the source is not published)
>
> There is an interesting document about reverse engineer of proprietary libopensc-dnie.so library at:
> http://espana.barrapunto.com/es/10/03/20/2251222.shtml
> The full pdf is at:
> http://blog.48bits.com/wp-content/uploads/2010/03/articulo.pdf
> (in spanish, sorry)
>
> There is also several people working in create a full source free driver for spanish eDNI card.
> In the meanwhile, I've developed a wrapper to create a fake function sc_driver_version() to tell opensc
> that proprietary library module version is ok.
>
> It's a dirty trick, but works. I've sent it to xxxx in a separate mail
> The free opensc spanish eDNI driver is still a political battle... but we are near to bypass politics :-b

Using the proprietary module loading interface was not the best solution but it worked and was OK for all parties. But as the signs currently show that they just abuse LGPL. And not in a chinese dvd player but in an EU government backed project - this can not be tolerated.

Such projects can often be partly funded by EU structure funds, do you know (or can you research) if this is the case for DNI as well? (Usually this means having the EU flag sign somewhere on the materials of the result of the project, like it is on the Portuguese card website http://www.cartaodocidadao.pt/ or Estonian eID https://id.eesti.ee/trac/ )

En cristiano: una cosa es dar facilidades al desarrollo y otra es no corresponder con esas facilidades. Algunos países, como Finlandia e italia directamente publicaron los drivers como código abierto. Otros, como Portugal y Estonia, empezaron con un driver cerrado, y luego lo abrieron...

Spain is different: no solo publicaron Ceres violando la GPL, y posteriormente como driver cerrado, sino que el eDNI es tambien cerrado, y no tienen la menor intención de abrirlo. La gente de OpenSC está amenazando (y con razón) con eliminar la posibilidad de carga dinámica de drivers, lo que dejaría literalmente tirada la posibilidad de usar el eDNI en Linux.

Asco de política..

Gegen die Dummheit kämpfen selbst die Götter vergebens - Schiller

naw's picture

Parece que van a mandar un mail


Parece que van a mandar un mail a los del dnielectronico español y a los del portugues
http://www.opensc-project.org/pipermail/opensc-devel/2010-March/013784.html

Si crees que estan violando la licencia tambien con CERES puede ser un buen momento para que lo comentes en la lista de correo.

En la web del dnie no he visto nada de europa, aunque supongo que en principio podria investigar en los presupuestos del estado a ver de donde ha salido el dinero... Lo que si te puedo decir es que se han usado fondos FEDER en la campaña de distribucion de lectores de dnie que hizo tractis, aunque en el CD solo venian drivers para Windows (en mac y linux te mandaban a la pagina web).

akas84's picture

Hola, Creo que aquí se están malinterpretando conceptos


Hola,

Creo que aquí se están malinterpretando conceptos. El código OpenSC está licenciado, como correctamente se indica en la parte citada bajo LGPL y por tanto ni CERES ni DNIe están violándola compilando un módulo binario para ello.

Además comentar que desde OpenSC[1] sólo se está pidiendo tanto al proyecto de Portugal como a la DGP que suministren el código fuente del opensc binario que se está distribuyendo para facilitar la instalación a los ciudadanos. Como se puede leer en el licenciamiento GPL y LGPL no es obligatorio PUBLICAR el código. El punto obligatorio es suministrarlo si alguien lo solicita. Entonces yo me pregunto:

¿Por qué tanto ruido? ¿Alguien ha solicitado el código y no se lo han dado?

Repito, el código de OpenSC, no el de opensc-ceres ni opensc-dnie que no están licenciados bajo ninguna licencia de código abierto.

Un saludo,
[1]: http://www.opensc-project.org/pipermail/opensc-devel/2010-March/013784.html

jonsito's picture

Hay varias cosas


Por lo que comentan en las listas de correo, el problema con el dnie no va con linux sino con MacOS. Parece ser que el binario distribuido para MacOS no utiliza los procedimientos de carga dinámica de linux sino que tiene el código empotrado dentro del de OpenSC. Esto sí contituye una clara violación de la licencia:

http://www.opensc-project.org/pipermail/opensc-devel/2010-March/013751.html

Yes, the Linux instructions talk about installing opensc and opensc-dnie which feels like you describe (and how I remember it was explained some years ago) But I suspect things have changed. The code that is installed with OS X is a single libopensc that contains a lot of mixed symbols, some of which don't exist in OpenSC code.
For example sc_pkcs15_get_card_objects in pkcs15_default.o, which also contains other symbols which indeed are in OpenSC.

So I think the module thing does not apply any more, at least not on OS X.

Por ello se ha abierto una incidencia, para preguntar y clarificar el status legal, y de paso solicitar que la DGP incluya en la página de descargas el fuente de OpenSC:
http://www.opensc-project.org/opensc/ticket/205

Por otro lado, el sentir de la gente de OpenSC es que "ya está bien". Que una cosa
es dar facilidades, y otra que se abuse de ellas.

Gegen die Dummheit kämpfen selbst die Götter vergebens - Schiller

akas84's picture

En ese caso jonsito, imagino


En ese caso jonsito, imagino que se refieren al software utilizado en el eID portugués ya que como se puede ver en www.dnielectronico.es el software que se utiliza es el SCA-0.2.2 que aunque es antiguo está compilado por el equipo de opensc.org.

El único punto a consultar referente al DNI electrónico Español es el código fuente de los paquetes binarios de opensc-0.11.7 que se distribuyen.

Un saludo,

jonsito's picture

Me temo que no ( y una buena noticia)


El caso portugues es totalmente distinto: la empresa que hizo el trabajo ha reconocido que utilizan una version modificada de OpenSC y están intentando con el gobierno portugues arreglar el desaguisado:

http://www.opensc-project.org/opensc/ticket/204
http://www.opensc-project.org/pipermail/opensc-devel/2010-March/013748.html

Por lo que he podido deducir, es que efectivamente, en el caso español, en lugar de opensc se utiliza SCA, que es un subset de opensc adaptado para el entorno criptográfico de los Mac.

Por lo que comentan en el correo, el binario que se proporciona para el edni (español) en los mac contiene diversas rutinas que parecen importadas de OpenSC. Es como si para aprovechar el código de linux, en el desarrollo se hubieran añadido a la biblioteca propietaria las rutinas de OpenSC que no existen en SCA.

------------------------------------------------------------------------------------------

Cambiando de Tema: para OpenSC-0.12, se acaba de aceptar la integración del DNI italiano:

http://www.opensc-project.org/opensc/ticket/177

Este DNI estaba soportado como un "separate fork" desde hace mucho tiempo, pero ahora
va a ser integrado totalmente con sus correspondientes fuentes

Lo mejor de todo es que el Italian eID incluye tambien el famoso "secure messaging".
En este momento están discutiendo la mejor manera de manejar las claves de apertura
del canal, así como la generación remota de comandos de control (procedimiento que
utiliza la versión java de la aplicación de cambio de contraseña para 0sX y Linux
en nuestro DNI)

La Buena noticia es que el sistema es calcadito del español, con lo que una vez
publicados estos fuentes, no habría razón real para seguir ocultando los fuentes españoles

Una razón más para intentar convencer a nuestros políticos de que se dejen de tonterías.

Esta siendo una larga lucha; pero ya se atisba el fin de la batalla :-)

Gegen die Dummheit kämpfen selbst die Götter vergebens - Schiller

akas84's picture

Me equivoqué


Me equivoqué y contesté al final. Ahora si:

No tiene ningun sentido que se hable de un sca modificado cuando en los manuales de instalacion del dni electrónico se ofrece un link de descarga a la web opensc-project.org. Puedes consultarlo en los manuales de www.dnielectronico.es

Un saludo

jonsito's picture

Diferentes changelogs??


Investigando por el web, me ha llamado la atención una cosa:

No existe el paquete opensc-0.11.7-7.fc10.i386.rpm en ningún otro sitio web que no sea el de la DGP

Es más: el changelog oficial del rpm de OpenSC dice algo tal que:

pepe$ rpm -qi --changelog opensc
-------
* lun jun 15 2009 Tomas Mraz <tmraz@redhat.com> - 0.11.8-2
- Rebuilt with new openct

* lun may 11 2009 Tomas Mraz <tmraz@redhat.com> - 0.11.8-1
- new upstream version - fixes security issue

* vie feb 27 2009 Tomas Mraz <tmraz@redhat.com> - 0.11.7-1
- new upstream version - fixes CVE-2009-0368
-----------------------------------

Es decir, se pasó directamente del 0.11.7-1 al 0.11.8-1 por un problema de seguridad

En cambio el changelog del rpm que ofrece la DGP dice lo siguiente:
rpm -qi opensc-0.11.7-7.fc10.i386.rpm
----------------------------------------------
...
such as the FINEID (Finnish Electronic IDentity) card. Swedish Posten
eID cards have also been confirmed to work.
* mié jun 03 2009 Dirección General de la Policía y de la Guardia Civil <oficinatecnica@dnielectronico.es> - 0.11.7-7
* Tue May 5 2009 Dirección General de la Policía y de la Guardia Civil

Gegen die Dummheit kämpfen selbst die Götter vergebens - Schiller

OtraVezAqui's picture

solicitar, suministrar...


uf...

cuando alguien lee la licencia , y lee debe suministrar el codigo supongo que todo el mundo espera que el codigo este disponible junto a su binario sin tener que SOLICITAR NADA....

no se, cuando empezamos a usar los "matices" de las palabras se pierde el espíritu del contexto.

y sip, debe suministrar <> lo mismo a debe publicar....

pero vamos....

anv's picture

alternativas


Bien, tenemos un problema, la gente que maneja esto no quiere liberar el código fuente de su driver.

Qué alternativas tenemos. La ideal sería presionarlos lo suficiente para que lo liberen. Dado que originalmente publicaron el driver violando la GPL, estan obligados a liberar esa versión, sin importar que hayan dejado de distribuirla. Pero dado que se trata del Estado, no se si se los logrará convencer. Tal vez con la ayuda legal de la Free Software Fundation...

Suponiendo que eso no se consiga, la siguiente alternativa es hacer un driver libre. Tengo entendido que hay gente trabajando en ello pero podría ocurrir, por ejemplo, que se encuentren con que el driver utiliza alguna clave para acceder al contenido. En ese caso podrían liberar todo menos la clave. Algo parecido a lo que ocurre con drivers para algunos dispositivos como modems ADSL o adaptadores WIFI por usb, que no tienen ROM así que el firmware se les sube cada ve que se inicializan. Como el firmware está incluido en el driver, se puede hacer un driver libre pero no se puede incluir el firmware y sin eso no funciona. También podría ser que para lograr el driver libre tuvieran que hacer ingeniería inversa y no se qué tan legal sea eso, considerando que el driver para linux sí existe (aunque sólo para algunas pocas versiones). Si no hubiera ningún driver par alinux se podría alegar que la ingeniería inversa es sólo para interoperabilidad.

La solución siguiente es forzar la carga del driver aunque la versión no sea la misma. Esto es una solución sucia pero que funciona, aunque no resuelve el problema real que es la falta del código fuente.

Como sea, estos problemas de versiones lamentablemente no sirven para que se den cuenta de que deben liberar el código. Lo único que hacen es reforzar la idea que tiene mucha gente de que la gran diversidad de versiones de Linux es un obstáculo. Los usuarios de Linux generalmente saben que ese obstáculo genera ventajas en muchos sentidos pero en realidad ellos no necesitan convencerse de que Linux es bueno y útil.

En definitiva, lo que debería ser una presión para que liberen el driver del dni electrónico en definitiva se convierte en una "mala propaganda" para Linux. Esperemos que pronto haya una solución aceptable al asunto y mientras tanto habrá que hacer trampas para poder usarlo.

Alejandro Nestor Vargas
http://theflatearthsociety.org/