1. The Development of the new
Free/Opensource Portuguese Card Citizen
middleware
Luis Medinas <luis.medinas@caixamagica.pt>
(Software Engineer)
http://twitter.com/lmedinas
3. O que vos trouxe até aqui ?
lv ido o Poss
o
envo aplic desenv
i des are ?
o fo lew C
? açõe olver
Com midd C s com nova
no vo do Q o CC
?
s
re uais
e wa Éu
ms
as c
id
dl imp apacid
m les ade
o ca rt s do
v ão d CC
no Com e ID ?
m o poss ou m
u o partic ais
ê ipar no ?
u novo m
orq iddlewa
P re ?
Como funciona o Cartão de Cidadão ?
4. Resumo
● SmartCards
● Cartão de Cidadão
● Desenvolvimento do novo Middleware
● Demonstração do Projeto
7. SmartCards – Cartão de Cidadão
● Obtenção dos atributos
● Informatica – SmartCard
● Visual – Zona de leitura por maquina (MRZ)
● Visual – Zona de leitura humana
8. SmartCards – Atributos Visuais
● Humano
● Nomes
● Atributos Físicos
● Números (NIF, Validade, NIC, etc...)
● Outros (Fotografia, Nacionalidade, etc...)
● MRZ
● Nome
● Números
11. SmartCards
● Cartão:
● CPU
● ROM
● EEPROM
● RAM
● 2 Applets diferentes (IAS/GEMSAFE)
12. Smartcards - Componentes
● CPU ● EEPROM
● 8/16 bits ● File System
● Rom ● Chaves
● Comunicação ● Pin's
● Sistema Operativo ● RAM (rm poweroff)
● Criptografia ● Contactos Mecânicos
● ISO 7816-2 ● Segurança Física
13. Smartcards - Comunicação
● Baixo nível
● T=0 (char level) e T=1 (block-level)
● ATR (ISO 7816-3)
● Alto nível
● APDU (Application Protocol Data Unit)
● ISO 7816-4
14. SmartCards – APDU
● Comando APDU
● CLA (1 byte)
– Classe de Instrução
● INS (1 byte)
– Tipo de Comando
● P1 & P2 (2 bytes)
– Parâmentros do Comando
● LC
– Tamanho opcional do Comando DATA
● DATA
● LE
– Tamanho da DATA esperado após a resposta APDU
19. Cartão de Cidadão – Auth/Sign
● Chaves Privadas
● Criadas no cartão
● Não saem do cartão
● Necessitam de um PIN
● Usadas para produzir assinaturas (encriptação)
20. Cartão de Cidadão – Autenticação
● Exemplos de Autenticação
● HTTPS (http//login.sapo.pt)
● 802.1X
● Processo
● Cartão assina dados
● Envia a assinatura, chaves públicas
● O receptor (Servidor) usa cadeias de certificação
● Extrai os dados das chaves públicas
21. Cartão de Cidadão – Assinatura
● Exemplos de Assinatura
● Ficheiros (*.doc, *.odt, *.pdf, etc...)
● Email
● Processo
● Assinatura → Hash do documento + Chave pública
do cartão
● Encriptação gerada com a chave privada
23. Cartão de Cidadão – EMV-CAP
● Applet no Cartão de Cidadão semelhante aos
VISA/MasterCards
● Usado para gerar o OTP
● Necessário para sincronização do 4º PIN
● 4º PIN
● Sincroniza com o PIN de Auth
● Utiliza Auth p/pkc11 com os Servidores de OTP
● Envia parâmetros ARQC, PIN, ATC, CDOL1...
24. Cartão de Cidadão - SAM
● Alterar a morada do Cidadão (EF05)
● Verificar o ficheiro SOD (EF06)
● Gravar a nova morada no cartão
26. Objectivos novo Middleware
● Realizar a comunicação entre o Cartão e o SO
● Envolver serviços SAM e OTP
● Multiplataforma (Windows, Linux, Mac OS X)
● Free/OpenSource Software
● Base estável e modular.
● Suporte para varias linguagens de programação (JAVA,
C++, C# (.NET))
● Documentação
● Developer-Friendly
● Realizar assinaturas “easy mode”
27. Middleware actual
● Closed Source
● Conceito obsoleto
● Problemas multi-arquitecturas
● Pouca documentação
● Não é Developer friendly
30. Como ?
● Utilização de FOSS
● Base moderna e aberta
● Comunidade
● Developers
31. Novo Middleware
● FOSS
● Projecto modular
● Baseado no beid-mw (http://goo.gl/ZTbQm)
● Multiplataforma (Windows, Linux, Mac OS X)
● Multiarquitectura (32/64 x86)
● Documentação
● Developers
● Comunidade
● Suporte Aplicacional
32. Tecnologias do novo Middleware
● PKCS#11
● Crypto API
● PCSC/WinScard
● Qt
● Eid-mw
● C/C++
● Java
● openssl
33. Arquitectura
MS Windows eidgui
Crypto API SDK Java .Net
CSP eidlib
AppLayer PKCS11 apps
CardLayer PKCS11
PCSC-lite
Kernel
34. Desafios de desenvolvimento
● Multiplatforma
● Sistema modular
● Compreensão das Applets
● Compatibilidade antecessor
● Serviços Web
● Contribuir Código
● Novas funcionalidades
● Código online (http://svn.gov.pt/projects/ccidadao)
35.
36. Hello World C++
//*****************************************************************************
// Show the info of the card in the reader
//***************************************************************************** //*****************************************************************************
// PTeID SDK sample code. void showCardInfo( const char* readerName )
// This sample demonstrates how to use the eID SDK to read a Portuguese eID card. {
// The program will dump the data to the standard output for each card reader PTEID_ReaderContext& readerContext = ReaderSet.getReaderByName( readerName );
// it finds. if ( readerContext.isCardPresent() )
//***************************************************************************** {
#include <iostream> //PTEID_CARDTYPE_EID:
#include "eidlib.h" getEidCardData( readerContext );
}
using namespace eIDMW; }
//***************************************************************************** //*****************************************************************************
// Get the data and dump to the screen // Show the reader info an get the data of the card if present
// Beware: The data coming from the cards is encoded in UTF8! //*****************************************************************************
//***************************************************************************** void showReaderCardInfo( const char* readerName )
void getEIDData( PTEID_EIDCard& card ) {
{ PTEID_ReaderContext& readerContext = ReaderSet.getReaderByName( readerName );
PTEID_EId& eid = card.getID();
std::cout << "Reader: " << readerName << std::endl;
if ( card.isTestCard() ) std::cout << "tCard present: " << (readerContext.isCardPresent()? "yes" :"no") << std::endl;
{
std::cout << "Error: This is a test card. Can not read data..." << std::endl; showCardInfo( readerName );
return;
} std::cout << std::endl;
}
std::cout << "tDocumentType : " << eid.getDocumentType() << std::endl;
//*****************************************************************************
std::cout << "tPersonal data:" << std::endl; // scan all the card readers and if a card is present, show the content of the
std::cout << "tFirstName : " << eid.getFirstName() << std::endl; // card.
std::cout << "tSurname : " << eid.getSurname() << //*****************************************************************************
std::endl; void scanReaders( void )
std::cout << "tGender : " << eid.getGender() << std::endl; {
std::cout << "tDateOfBirth : " << eid.getDateOfBirth() << std::endl; unsigned long nrReaders = ReaderSet.readerCount();
std::cout << "tLocationOfBirth : " << eid.getLocationOfBirth() << std::endl; const char* const* readerList = ReaderSet.readerList();
std::cout << "tNationality : " << eid.getNationality() << std::endl;
std::cout << "tNationalNumber : " << eid.getNationalNumber() << std::endl; std::cout << "Nr of card readers detected: " << nrReaders << std::endl;
std::cout << "tMemberOfFamily : " << eid.getMemberOfFamily() << std::endl;
std::cout << "tValidityBeginDate : " << eid.getValidityBeginDate() << std::endl; for ( size_t readerIdx=0; readerIdx<nrReaders; readerIdx++)
std::cout << "tValidityEndDate : " << eid.getValidityEndDate() << std::endl; {
showReaderCardInfo( readerList[readerIdx] );
PTEID_EIdAddress& eidaddress = card.getAddr(); }
std::cout << "tStreet : " << eidaddress.getStreet() << }
std::endl;
std::cout << "tZipCode : " << eidaddress.getZipCode() << //*****************************************************************************
std::endl; // Main entry point
std::cout << "tMunicipality : " << eidaddress.getMunicipality() << std::endl; //*****************************************************************************
std::cout << "tIssuingMunicipality: " << eidaddress.getIssuingMunicipality() << std::endl; int main( int argc, char* argv[] )
} {
std::cout << "PTeID SDK C++ sample program: read_eid" << std::endl;
//*****************************************************************************
// Get the data from a Portuguese EID card scanReaders();
//*****************************************************************************
void getEidCardData( PTID_ReaderContext& readerContext ) PTEID_ReleaseSDK();
{
PTEID_EIDCard& card = readerContext.getEIDCard(); }
getEIDData(card);
}
37. Hello World Java
//*****************************************************************************
// Get the data from a Portuguese EID card
//***************************************************************************** //*****************************************************************************
// eID SDK sample code. private static void getEidCardData(PTEID_ReaderContext readerContext) throws Exception
// This sample demonstrates how to use the eID SDK to read a Portuguese eID card. {
// The program will dump the data to the standard output for each card reader PTEID_EIDCard card = readerContext.getEIDCard();
// it finds. getEIDData(card);
// }
// compile:
// javac -classpath <path_to>pteid[35]libJava.jar main.java //*****************************************************************************
// // Show the info of the card in the reader
// run (windows): //*****************************************************************************
// set PATH=<path_to_dll's>;%PATH% private static void showCardInfo(String readerName) throws Exception
// java -cp <path_to>pteid35libJava.jar;. main {
//***************************************************************************** PTEID_ReaderContext readerContext =
PTEID_ReaderSet.instance().getReaderByName( readerName );
import java.lang.*; if ( readerContext.isCardPresent() )
import pt.portuguese.eid.*; {
System.out.println("tType : " + getCardTypeStr(readerContext));
public class main
{ PTEID_CardType cardType = readerContext.getCardType();
//***************************************************************************** getEidCardData(readerContext);
// Get the data and dump to the screen }
// Beware: The data coming from the cards is encoded in UTF8! }
//*****************************************************************************
private static void getEIDData(PTEID_EIDCard card) throws Exception //*****************************************************************************
{ // Show the reader info an get the data of the card if present
PTEID_EId eid = card.getID(); //*****************************************************************************
private static void showReaderCardInfo(String readerName) throws Exception
System.out.println( "tDocumentType : " + eid.getDocumentType() ); {
PTEID_ReaderContext readerContext =
System.out.println( "tPeronal data:" ); PTEID_ReaderSet.instance().getReaderByName( readerName );
System.out.println( "t-------------" );
System.out.println( "tFirstName1 : " + eid.getFirstName1() ); System.out.println("Reader: "+readerName);
System.out.println( "tSurname : " + eid.getSurname() System.out.println("tCard present: " + (readerContext.isCardPresent()? "yes" :"no"));
);
System.out.println( "tGender : " + eid.getGender() showCardInfo( readerName );
);
System.out.println( "tDateOfBirth : " + eid.getDateOfBirth() ); System.out.println("");
System.out.println( "tLocationOfBirth : " + eid.getLocationOfBirth() ); }
System.out.println( "tNationality : " + eid.getNationality() );
System.out.println( "tNationalNumber : " + eid.getNationalNumber() ); //*****************************************************************************
System.out.println( "tSpecialOrganization: " + eid.getSpecialOrganization() ); // scan all the card readers and if a card is present, show the content of the
System.out.println( "tMemberOfFamily : " + eid.getMemberOfFamily() ); // card.
System.out.println( "tValidityBeginDate : " + eid.getValidityBeginDate() ); //*****************************************************************************
System.out.println( "tValidityEndDate : " + eid.getValidityEndDate() ); private static void scanReaders() throws Exception
{
PTEIDAddress_EId eidaddress = card.getAddr(); long nrReaders = PTEID_ReaderSet.instance().readerCount();
System.out.println( "tStreet : " + eid.getStreet() System.out.println("Nr of card readers detected: "+nrReaders);
);
System.out.println( "tZipCode : " + eid.getZipCode() for ( int readerIdx=0; readerIdx<nrReaders; readerIdx++)
); {
System.out.println( "tMunicipality : " + eid.getMunicipality() ); String readerName = PTEID_ReaderSet.instance().getReaderName(readerIdx);
System.out.println( "tCountry : " + eid.getCountry() showReaderCardInfo(readerName);
); }
System.out.println( "tIssuingMunicipality: " + eid.getIssuingMunicipality() ); }
}