votac¸ao digital em celulares˜ - coordenação de projetos · satsa api para java me com recursos...

129
UNIVERSIDADE FEDERAL DE SANTA CATARINA DEPARTAMENTO DE INFORM ´ ATICA E ESTAT ´ ISTICA BACHARELADO EM CI ˆ ENCIA DA COMPUTAC ¸ ˜ AO Abimael Aldevino Fidˆ encio Andr´ e Ricardo Natal Sim ˜ oes Votac ¸˜ ao Digital em Celulares Trabalho de Conclus˜ ao de Curso submetido ` a Universidade Federal de Santa Cata- rina como parte dos requisitos para a obtenc ¸˜ ao do grau de Bacharel em Ciˆ encia da Computac ¸˜ ao. Marcelo Luiz Brocardo Orientador Prof. Ricardo Felipe Cust ´ odio, Dr. Co-Orientador Florian´ opolis, junho de 2011

Upload: lyphuc

Post on 18-May-2018

213 views

Category:

Documents


1 download

TRANSCRIPT

UNIVERSIDADE FEDERAL DE SANTA CATARINADEPARTAMENTO DE INFORMATICA E ESTATISTICA

BACHARELADO EM CIENCIA DA COMPUTACAO

Abimael Aldevino FidencioAndre Ricardo Natal Simoes

Votacao Digital em Celulares

Trabalho de Conclusao de Curso submetido a Universidade Federal de Santa Cata-

rina como parte dos requisitos para a obtencao do grau de Bacharel em Ciencia da

Computacao.

Marcelo Luiz BrocardoOrientador

Prof. Ricardo Felipe Custodio, Dr.Co-Orientador

Florianopolis, junho de 2011

Votacao Digital em Celulares

Abimael Aldevino FidencioAndre Ricardo Natal Simoes

Este Trabalho de Conclusao de Curso foi julgado adequado para a obtencao do tıtulo de

Bacharel em Ciencia da Computacao e aprovada em sua forma final pelo Departamento

de Informatica e Estatıstica da Universidade Federal de Santa Catarina.

Prof. Vitorio Bruno Mazzola, Dr.

Coordenador do Curso

Banca Examinadora

Marcelo Luiz Brocardo

Prof. Ricardo Felipe Custodio, Dr.

Vitorio Bruno Mazzola, Dr.

iii

Que o mel e doce e coisa que eu me nego afirmar mas queparece doce isso eu afirmo plenamente

Raul Seixas

iv

Oferecemos este trabalho aos nossos pais, por terem nos

fornecido condicoes de estudar e chegarmos aonde

chegamos.

Agradecimentos

Agradecemos aos nossos pais pelo apoio e ajuda.

Sumario

Lista de Figuras ix

Lista de Siglas x

Resumo xii

Abstract xiii

1 Introducao 1

1.1 Contextualizacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.2 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.3 Objetivos Especıficos . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.4 Justificativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.5 Limitacoes do Trabalho . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Levantamento Tecnologico 4

2.1 Dispositivos Moveis . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.2 Java ME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.2.1 Arquitetura Java ME . . . . . . . . . . . . . . . . . . . . . . 5

2.3 Satsa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.3.1 Modulos arquiteturais . . . . . . . . . . . . . . . . . . . . . 7

2.3.2 Modelo de comunicacao . . . . . . . . . . . . . . . . . . . . 8

2.4 Ambiente de desenvolvimento . . . . . . . . . . . . . . . . . . . . . 9

2.4.1 Netbeans . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

vii

2.4.2 Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.4.3 Postgres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.4.4 Emuladores Utilizados . . . . . . . . . . . . . . . . . . . . . 10

3 Revisao Literaria 12

3.1 Votacao Digital . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3.1.1 Votacao Indireta e Votacao Direta . . . . . . . . . . . . . . . 12

3.1.2 Tipo de Voto . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.1.3 Atores Participantes de uma Votacao Digital . . . . . . . . . . 13

3.1.4 Atores Ativos e Atores Passivos . . . . . . . . . . . . . . . . 13

3.1.5 Confianca nos Atores da Votacao . . . . . . . . . . . . . . . 15

3.2 Bouncy Castle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.3 Fundamentos de Criptografia . . . . . . . . . . . . . . . . . . . . . . 16

3.3.1 Introducao . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.3.2 Criptografia Simetrica . . . . . . . . . . . . . . . . . . . . . 17

3.3.3 Criptografia Assimetrica . . . . . . . . . . . . . . . . . . . . 18

3.4 ElGamal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.5 Rede de Misturadores . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4 Prototipo do Sistema de Votacao em Dispositivos Moveis 23

4.1 Preparacao do ambiente . . . . . . . . . . . . . . . . . . . . . . . . . 23

4.2 Prototipo Votacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

4.2.1 Arquitetura . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4.2.2 Casos de Uso . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.2.3 Diagramas . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4.2.4 Apresentacao da Aplicacao . . . . . . . . . . . . . . . . . . . 37

5 Conclusao 45

Referencias 47

viii

A Codigo Fonte 49

A.1 Servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

A.2 Cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

B Codigo Fonte Rede Misturadores 81

B.1 Como Executar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

Lista de Figuras

2.1 Arquitetura do J2ME e relacao com o restante famılia Java . . . . . . 5

2.2 A Arquitetura Java 2 Micro Edition (J2ME) . . . . . . . . . . . . . . 5

2.3 APIs do SATSA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.4 Interacao dos MIDlets com os applets . . . . . . . . . . . . . . . . . 8

3.1 Ilustracao do funcionamento da criptografia simetrica. . . . . . . . . . 17

3.2 Processo de criptografia e distribuicao da chave secreta na criptografia

hıbrida. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.3 Ilustracao mostrando embaralhamento das mensagens em cada um dos

nodos da rede. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

4.1 Casos de Uso Servidor . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.2 Casos de Uso Votante . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.3 Tela Inicial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.4 Cadastro Eleicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

4.5 Cadastro do Votante . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

4.6 Listagem das Disputas . . . . . . . . . . . . . . . . . . . . . . . . . 40

4.7 Login . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.8 Escolha do candidato com listagem . . . . . . . . . . . . . . . . . . . 42

4.9 Escolha do candidato por codigo . . . . . . . . . . . . . . . . . . . . 42

4.10 Escolha do candidato por codigo . . . . . . . . . . . . . . . . . . . . 43

4.11 Fluxo de votacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

xi

Lista de Siglas

LabSEC Laboratorio de Seguranca em Computacao - UFSCNIP Numero de Identificacao Pessoal (PIN - Personal Identification

Number)ICP Infra-Estrutura de Chaves Publicas (PKI - Public Key Infrastruc-

ture)RNP Rede Nacional de Ensino e PesquisaRSA Rivest-Shamir-AdlemanSSL Protocolo de Camada de Sockets Segura (Secure Sockets Layer)TLS Seguranca da Camada de Transporte (Transport Layer Security)PCV Processo Cliente de VotacaoPSV Processo Servidor de VotacaoJCE Java Cryptographic ExtensionME Plataforma para Dispositivos Moveis (Mobile Edition)SE Plataforma padrao (Standart Edition)EE Plataforma Empresarial (Enterprise Edition)CLDC Configuracao para Dispositivos Moveis Limitados (Connected

Limited Device Configuration)CDC Configuracao para Dispositivos Moveis com maior poder

computacao (Connected Devide Configuration)MIDP Perfil JavaME para Dispositivos CLDC (Mobile Information De-

vice Profile)IMP Subconjunto do MIDP utilizado em dispositivos com uma inter-

face mais limitada (Information Module Profile)KVM Maquina Virtual Java utilizada em Dispositivos Moveis (K Vir-

tual Machine)IDE Ambiente Integrado de Desenvolvimento (Integrated Develop-

ment Environment)PDA Assistente Pessoal Digital (Personal digital assistants)API Interface de Programacao de Aplicacoes (Application Program-

ming Interface)SATSA API para Java ME com recursos de criptografia (The Security and

Trust Services API)PSV Processo Servidor de Votacao

Resumo

A necessidade da informacao a toda hora e lugar, fez com que os dispo-

sitivos moveis, principalmente os celulares, se tornassem muito populares. Tendo em

vista esse fato, cada vez mais, ha necessidade de se desenvolverem variados tipos de

aplicativos para os celulares.

O projeto tem por objetivo elaborar um prototipo de um sistema de votacao

via internet para celulares, tomando como estudo algoritmos de criptografia, visando a

seguranca do sistema como um todo, assim como respeitando a privacidade do usuario

Palavras chave: Votacao, Votacao Segura, Dispositivos Moveis, Crip-

tografia Assimetrica.

Abstract

The need for information all the time and place, made the devices, espe-

cially cell phones, became very popular. Considering this fact, increasingly, there is a

need to develop various types of applications for mobile phones. The project aims to

develop a prototype of a voting system for internet mobile phones, using as a study of

encryption algorithms, for the security of the system as a whole as well as respecting

the privacy of the User.

Keywords: Vote, secure vote, mobile devices, asymmetric cryptography.

Capıtulo 1

Introducao

A primeira vista, a mobilidade aparentava ser apenas mais uma facilidade,

mas atualmente insere-se no cotidiano como uma necessidade.

Hoje, muitas pessoas afirmam que nao conseguem mais viver sem os celu-

lares, outras dizem que atraves deles podem estar disponıveis 24 horas por dia em

qualquer lugar que se encontrem.

A popularizacao do segmento de dispositivos moveis foi rapida, em virtude

deste tipo de tecnologia permitir acesso a informacoes e dados a todo lugar e momento.

Nos ultimos anos foram conduzidas varias experiencias para facilitarem o

processo de eleicao. As facilidades foram introduzidas atraves de novas formas de ex-

pressar votos, alem das tradicionais baseadas em papel. Exemplos de novas interfaces

e sistemas de votacao sao os touch screens, mensagens SMS de telemoveis e sistemas

de votacao distribuıdos sobre a Internet, conforme definido em trabalho de final de

curso dos alunos Luıs Miguel Silva Costa e Nuno Alexandre Costa Freta dos Santos

([LUI 06], 2006 p. 8).

Esses novos sistemas de votacao possuem diversos atrativos, pois possuem

caracterısticas que os sistemas fısicos nao permitem, como a nao necessidade de deslo-

camento para votar, a possibilidade de boletins para verificar o voto, alem de maturi-

dade das pessoas em lidar com as novas tecnologias.

2

1.1 Contextualizacao

Existem diversos sistemas de e-voto1 , em desenvolvimento e na fase de

testes, mas sao pouquıssimos os sistemas que trabalham com votacao, em celulares,

pela grande limitacao de recursos imposta por esses aparelhos.

1.2 Objetivo

Este trabalho tem como objetivo a elaboracao de um sistema de votacao

em celulares para o estudo de tecnicas de seguranca e privacidade que um sistema de

votacao democratico necessita.

1.3 Objetivos Especıficos

Os objetivos especıficos deste trabalho sao:

• Estudar conceitos e tecnicas de seguranca para um sistema de votacao digital;

• Incentivar o uso de aplicativos moveis seguros;

• Desenvolver um prototipo de votacao para aplicativos moveis;

• Estudar a plataforma J2ME.

1.4 Justificativa

O avanco tecnologico gerou a necessidade de novas formas de desenvolver

sistemas de votacao eletronica como meio de expressar a vontade de comunidades de

uma sociedade digital, que impossibilita o recurso ao contato fısico entre os diversos

intervenientes no processo de votacao.

1Voto Eletronico

3

1.5 Limitacoes do Trabalho

Uma das limitacoes deste trabalho e a dificuldade em lidar com disposi-

tivos moveis, os varios sistemas operacionais e hardwares existentes em cada um.

Capıtulo 2

Levantamento Tecnologico

Neste capıtulo serao apresentados as tecnologias e os dispositivos utiliza-

dos no desenvolvimento deste prototipo.

2.1 Dispositivos Moveis

A primeira vista, a mobilidade aparentava ser apenas mais uma facilidade,

mas atualmente insere-se no cotidiano como uma necessidade. Hoje, muitas pessoas

afirmam que nao conseguem mais viver sem os celulares, outras dizem que atraves

deles podem estar disponıveis 24 horas por dia em qualquer lugar que se encontrem.

A popularizacao do segmento de dispositivos moveis foi rapida, em virtude deste tipo

de tecnologia permitir acesso a informacoes e dados a todo lugar e momento.

2.2 Java ME

Java Micro Edition, ou ainda J2ME, e uma tecnologia que possibilita o de-

senvolvimento de software para sistemas embarcados, ou seja, aqueles com reduzidas

capacidades de memoria e de processamento.

A plataforma J2ME e constituıda por um conjunto de APIs padrao definidas

pelo programa Java Community Process [JCP 11]. A plataforma J2ME esta hoje em

5

dia presente em milhoes de dispositivos (celulares, PDAs, dispositivos automoveis),

isso permite que uma aplicacao escrita uma unica vez possa ser executada numa larga

variedade de dispositivos.

A Figura 2.1 apresenta uma visao geral da arquitetura da famılia de platafor-

mas Java, incluindo o J2EE, J2SE, J2ME e Java Cards.

Figura 2.1: Arquitetura do J2ME e relacao com o restante famılia Java

2.2.1 Arquitetura Java ME

A arquitetura da plataforma J2ME e dividida em tres camadas: Maquina

Virtual, Configuracoes e Perfis, como mostrado na Figura 2.2.

Figura 2.2: A Arquitetura Java 2 Micro Edition (J2ME)

6

Configuracao trata-se de um conjunto de bibliotecas basicas disponıveis

para o programador. Ela tambem define qual o nıvel de servicos e funcionalidades

oferecidos pela maquina virtual. Uma configuracao e definida para uma variedade de

dispositivos com diferentes aplicacoes, mas com caracterısticas em comum. Exemplo:

dispositivos com comunicacao wireless como celulares, PDA’s, pagers, etc. Atual-

mente existem 2 configuracoes definidas:

• CLDC (Connected Limited Device Configuration): usado em dispositivos limi-

tados como celulares, PDA’s e pagers;

• CDC (Connected Devide Configuration): usado em dispositivos com maior ca-

pacidade (processamento e memoria) como sistemas de navegacao de carros e

televisores com conexao a Internet.

Cada perfil especifica um conjunto de bibliotecas para as classes de dis-

positivos. Cada perfil e sempre definido para uma determinada configuracao, mas uma

configuracao pode suportar varios perfis. Dois perfis sao definidos para o CLDC:

• MIDP (Mobile Information Device Profile);

• IMP (Information Module Profile).

A maquina virtual define quais as limitacoes dos programas que executarao

no dispositivo. A maquina virtual correspondente ao CLDC e chamada KVM, dese-

nhada especialmente para dispositivos pequenos e com recursos limitados. A KVM

mantem os aspectos centrais da Maquina Virtual Java e tem tamanho reduzido.

Para a plataforma Java ME existem tambem bibliotecas chamadas de pa-

cotes opcionais. Tratam-se de bibliotecas de programacao especıficas para uma de-

terminada tecnologia. Elas aumentam a capacidade do ambiente, caso estejam sendo

usadas no dispositivo.[CRI 11]

7

2.3 Satsa

De acordo com Ortiz (2005, apud [DAV 09], 2009) a SATSA (Security

and Trusted Services API) e uma Optional Package que estende as funcionalidades de

seguranca para a plataforma J2ME.

Esta extensao adiciona APIs criptograficas, de servicos de assinaturas dig-

itais e de gestao de certificados. Adicionalmente, sao definidos dois modulos - SATSA-

APDU e SATSA-JCRMI - que, juntamente com extensoes a Generic Connection Frame-

work (ver secao anterior), providenciam uma API que permite as aplicacoes J2ME

comunicar com elementos seguros (ver Figura 2.3).

Figura 2.3: APIs do SATSA

2.3.1 Modulos arquiteturais

A SATSA e constituıda pelos seguintes quatro modulos, cuja funcionali-

dade se descreve:

• SATSA-APDU: oferece suporte para a comunicacao com as aplicacoes que estao

presentes no smart card;

8

• SATSA-JCRMI: permite que aplicacoes J2ME (i.e. MIDlets) efetuem invocacoes

sobre objetos Java a executarem-se no smart card;

• SATSA-PKI: permite efetuar a geracao de assinaturas digitais ao nıvel da aplicacao

e gestao de certificados;

• SATSA-CRYPTO: e uma biblioteca criptografica generica para J2ME.

2.3.2 Modelo de comunicacao

O modelo de comunicacao do SATSA relaciona-se com a utilizacao das

APIs SATSA-APDU e SATSA-JCRMI. Ao estenderem o J2ME estas suportam a intera-

cao das aplicacoes J2ME do celular, os MIDlets, com aplicacoes residentes nos smart

cards, as applets (ver Figura 2.4). Atraves desta interacao e possıvel realizar diversos

servicos, tais como o armazenamento seguro de dados.

Figura 2.4: Interacao dos MIDlets com os applets

A comunicacao entre os MIDlets e os applets e baseada num modelo sıncro-

no de pedido/resposta, onde o MIDlet toma o papel de cliente na interacao e o applet

toma o papel de servidor. Esta comunicacao e realizada atraves do envio de APDUs

(Application Protocol Data Units), que correspondem a tramas de dados em bits. Na

comunicacao com Java Cards este modelo e simplificado atraves do modulo SATSA-

JCRMI, providenciando um modelo orientado a objetos que abstrai a troca dessas tra-

mas.

9

2.4 Ambiente de desenvolvimento

O desenvolvimento da aplicacao Java ME foi realizado no ambiente inte-

grado de desenvolvimento (Integrated Development Environment - IDE) de software

NetBeans versao 6.9.1, desenvolvido pela Sun Microsystems.

2.4.1 Netbeans

O Netbeans e uma IDE e gratuita, facil instalacao e que roda em diversas

plataformas, incluindo Windows, Linux, Mac OS X e Solaris. Essa IDE fornece ferra-

mentas para o desenvolvimento de aplicacoes para dispositivos moveis que utilizam a

linguagem Java.

O Netbeans possibilita a criacao, teste, depuracao e tambem a implantacao

de aplicacoes desenvolvidas para os perfis MIDP, configuracoes CLDC e CDC.

Possui uma ferramenta que faz a analise do codigo, com o intuito de diminu-

ir o tamanho da aplicacao identificando componentes que nao estao sendo utilizados e

verifica a compatibilidade com o perfil MIDP 1.0.

2.4.2 Eclipse

Eclipse e uma IDE (ambiente de desenvolvimento integrado) e um extenso

sistema de plugins. E escrito principalmente em Java e pode ser usado para desenvolver

aplicacoes em Java e, por meio de diversos plugins, outras linguagens de programacao

como Ada, C, C++, Cobol, Perl, PHP e diversas outras.

A IDE Eclipse para desenvolvedores Java EE contem tudo que voce precisa

para construir aplicacoes em Java e Java Enterprise Edition (Java EE). Considerado

por muitos a melhor ferramenta de desenvolvimento Java disponıvel. A IDE Eclipse

para desenvolvedores Java EE fornece compilacao incremental, um editor grafico de

HTML / JSP / JSF, ferramentas de gerenciamento de banco de dados e suporte para os

mais populares servidores de aplicacoes. [WES 11]

10

2.4.3 Postgres

Como informado na webpage do postgres [POS 11] ferramenta PostgreSQL

e um poderoso sistema gerenciador de banco de dados objeto-relacional de codigo

aberto. E um sistema com mais de 15 anos de desenvolvimento e sua arquitetura

possue uma forte reputacao de confiabilidade, integridade de dados e conformidade a

padroes. Uma grande vantagem e o fato de rodar em todos os grandes sistemas op-

eracionais, incluindo GNU/Linux, Unix (AIX, BSD, HP-UX, SGI IRIX, Mac OS X,

Solaris, Tru64), e MS Windows.

Como um banco de dados de nıvel corporativo, o PostgreSQL possui fun-

cionalidades sofisticadas como o controle de concorrencia multiversionado (MVCC,

em ingles), recuperacao em um ponto no tempo (PITR em ingles), tablespaces, replica-

cao assıncrona, transacoes agrupadas (savepoints), copias de seguranca a quente (on-

line/hot backup), um sofisticado planejador de consultas (otimizador) e registrador de

transacoes sequencial (WAL) para tolerancia a falhas.

Suporta conjuntos de caracteres internacionais, codificacao de caracteres

multibyte, Unicode e sua ordenacao por localizacao, sensibilidade a caixa (maiusculas

e minusculas) e formatacao. E altamente escalavel, tanto na quantidade enorme de

dados que pode gerenciar, quanto no numero de usuarios concorrentes que pode aco-

modar.

Existem sistemas ativos com o PostgreSQL em ambiente de producao que

gerenciam mais de 4TB de dados.

2.4.4 Emuladores Utilizados

O desenvolvimento de aplicacoes para dispositivos moveis requer a utiliza-

cao de emuladores de plataformas. As plataformas alvo da ferramenta proposta sao

Java ME perfil MIDP versao 2.1, configuracao CLDC versao 1.1. As secoes sub-

sequentes apresentam os emuladores selecionados para o desenvolvimento e teste. Para

a plataforma Java ME foi escolhido o emulador Sun Java Wireless Toolkit.

Como citado por Davi Garcia Pereira [DAV 09], o kit de desenvolvimento

11

da aplicacao esco-lhido foram: Sun Wireless Toolkit para CLDC versao 2.5.2, uti-

lizando a configuracao CLDC com o perfil MIDP.

Trata-se de um conjunto de ferramentas que torna possıvel criar aplicacoes

para telefones celulares e outros dispositivos sem fio. Apesar do fato de utilizarmos o

perfil MIDP 2.1, o Sun Wireless Toolkit para CLDC tambem suporta muitos pacotes

opcionais. Incluindo ambientes de emulacao, otimizacao de desempenho e ajuste de

recursos, documentacao, e exemplos. O Sun Wireless Toolkit inclui muitos recursos

amigaveis ao desenvolvedor. Alguns deles sao:

• Suporte as APIs padrao:

1. CLDC versao 1.1 (JSR 139);

2. MIDP versao 2.0 (JSR 118);

3. Wireless Messaging API (JSR 205);

4. Mobile Media API (JSR 135);

5. SATSA API (JSR 177); e outras.

• Escolha da interface do emulador;

• Cria projetos de arquivos JAR e JAD;

• Suporta outros emuladores;

• Aplicacoes de demonstracao; e outras.

Capıtulo 3

Revisao Literaria

3.1 Votacao Digital

O conceito de votacao e amplo e vai alem das conhecidas eleicoes. Tambem

aplica-se a tudo que envolva a reuniao de pessoas para a escolha de algo.

3.1.1 Votacao Indireta e Votacao Direta

Conforme definiu Araujo ([ARA 02], 2002 p. 11), basicamente existem

duas formas principais de votacao, a indireta e a direta.

A votacao indireta ocorre normalmente em situacoes na qual lidamos com

uma grande quantidade de votantes e muitas questoes a serem decididas. Reunir essa

grande quantidade de pessoas e um processo de um custo relativamente alto e leva

um grande tempo para ser apurado. Em virtude desse fato e outros que podem surgir,

opta-se por se fazer o processo de maneira indireta. Dessa maneira os votantes elegem

representantes e estes votam sobre as decisoes de interesse dos votantes.

A votacao direta ocorre em outras situacoes onde se tem um numero de

votantes consideravelmente pequeno, nesse caso e mais facil reunir um mınimo neces-

sario de pessoas para efetuar a votacao. Dessa maneira mesmo com um grande numero

de decisoes a serem tomadas pode-se efetuar a votacao com um custo relativamente

baixo. Neste tipo de votacao os votantes expressam suas opinioes diretamente.

13

3.1.2 Tipo de Voto

Em uma votacao pode-se ter o conceito de voto ponderado na qual se

atribuem diferentes pesos aos votos durante uma tomada de decisao.

Um exemplo de ponderacao seria o caso mostrado na dissertacao de mestrado

de Roberto Araujo ([ARA 02], 2002 p. 12), no qual em uma empresa pode-se ter diver-

sos acionistas e cada um desses possuir um numero diferente de acoes. Dessa maneira,

os votos dos acionistas com maior numero de acoes teriam um peso maior no resultado

final da apuracao do que os votos dos acionistas minoritarios.

Tambem existe o conceito no qual nao e usada a ponderacao, isso e abor-

dado por exemplo nas eleicoes municipais, nas quais todos os votos tem o mesmo

peso.

3.1.3 Atores Participantes de uma Votacao Digital

De acordo com Araujo ([ARA 02], 2002 p. 12) em votacoes conven-

cionais, aquelas que usam cedulas e papel e urnas, normalmente existe um conjunto de

pessoas com funcoes especıficas. Por exemplo, as pessoas que fiscalizam e adminis-

tram para que nao hajam fraudes ou falhas no processo de votacao.

3.1.4 Atores Ativos e Atores Passivos

Os atores do ambiente de votacao digital: votante; meio de comunicacao e

o sistema de votacao podem ser atores ativos e atores passivos.

Atores ativos sao aqueles que realizam processamento de informacoes e

portanto tem poder computacional e atores passivos sao aqueles que nao possuem

poder computacional. O votante e o ator que vota, porem para que seja possıvel para o

mesmo realizar o ato do voto, e necessario que ele possua software e hardware.

Conforme definido na tese de mestrado de Araujo ([ARA 02], 2002 p.

14), denomina-se Processo Cliente de Votacao (PCV), o conjunto software/hardware

necessario para emitir o voto. Nesse caso estamos assumindo que o PCV e o indivıduo

14

que utiliza o PCV para votar, sao uma entidade unica. De maneira semelhante, o con-

junto software/hardware do sistema de votacao deve cumprir requisitos mınimos para

conduzir o processo de votacao. Esse conjunto software/hardware descrito anterior-

mente e denominado Processo Servidor de Votacao (PSV).

Tanto o PCV quanto o PSV sao atores ativos precisam realizar computacao

principalmente relativas a criptografia. O meio de comunicacao e um ator passivo pois

nao precisa realizar nenhum tipo de computacao relacionado diretamente ao processo

de votacao. A funcao do meio de comunicacao e de estabelecer a comunicacao entre

os atores ativos, para que os mesmos sejam capazes de trocarem informacoes.

No desenvolvimento desse trabalho foram considerados dois principais

atores:

Administrador:

• O administrador do sistema tem o papel de preparar o sistema, atribuindo requi-

sitos necessarios para a votacao, tais como:

1. Cadastro de eleicao(oes);

2. Cadastro de disputa(s) para cada Eleicao;

3. Cadastro de candidato(s) para cada Disputa;

4. Cadastro de votantes;

5. Habilitar o votante para a(s) eleicao(oes).

Votante:

• Trata-se do perfil principal do prototipo,

1. O perfil de votante e atribuıdo a todos que estao aptos a votar em eleicoes

pre-determinadas;

2. Cabe a ele escolher quais das eleicoes (que o mesmo esteja habilitado) ira

votar;

15

3.1.5 Confianca nos Atores da Votacao

Um esquema de votacao digital e uma aplicacao distribuıda constituıda

por um conjunto de protocolos e mecanismos criptograficos que juntos permitem que

uma votacao aconteca inteiramente sobre redes de computadores, de maneira segura,

mesmo assumindo que seus legıtimos participantes possam ter comportamento mali-

cioso, Riera (1999, apud [ARA 02], 2002, p. 15).

Para um funcionamento perfeito de um esquema de votacao e necessario

que os tres principais atores (votante, canal de comunicacao e o sistema de votacao -

PSV) sejam totalmente confiaveis.

Um sistema de votacao digital e malicioso se possibilitar que qualquer ator,

participante ou nao do processo, altere o resultado final da votacao. Para resolvermos

problemas relativos a maliciosidade de um sistema de votacao digital e de todas as

entidades envolvidas no processo, e necessario que seja utilizado um protocolo crip-

tografico de votacao digital e que esse atenda a determinados requisitos de seguranca.

Alem de participantes do processo de votacao considerados legıtimos poderem ser ma-

liciosos, ainda ha a possibilidade de que agentes externos tentarem de alguma maneira

influir maliciosamente no processo de votacao.

3.2 Bouncy Castle

The Legion of Bouncy Castle iniciou como uma iniciativa para a implemen-

tacao de um provedor de criptografia para o Java Cryptographic Extension (JCE) to-

talmente gratuito e de codigo aberto ([AND 07], 2007).

A implementacao foi organizada de tal forma que pode ser empacotada

tanto para Java SE como para Java ME. Por ser um projeto de codigo aberto, esta bi-

blioteca apresenta uma serie de vantagens, enumeradas por Yuan (2003, apud [AND 07],

2007) na seguinte lista:

• Bugs ou falhas de seguranca sao corrigidos rapidamente;

16

• As APIs foram projetadas de forma flexıvel, e juntamente com o modelo de de-

senvolvimento comunitario, permitem que qualquer desenvolvedor possa con-

tribuir com novas implementacoes de algoritmos. Consequentemente, a bib-

lioteca implementa um grande numero de algoritmos conhecidos;

• A comunidade de desenvolvedores esta sempre otimizando as implementacoes

existentes, garantindo a melhoria do desempenho das operacoes criptograficas;

• E gratuita.

Esta biblioteca suporta uma diversidade muito grande de algoritmos, sendo

bem completa e funcional, apresentando muito mais opcoes de algoritmos e operacoes

criptograficas (hash, por exemplo) quando comparada com os pacotes opcionais da

SATSA (Pacote [Optional Package] que estende as funcionalidades de seguranca para

a plataforma J2ME). Porem, ao contrario da SATSA, nao e padronizada como pacotes

opcionais, nao sendo portanto, suportada nativamente pelos dispositivos, o que oca-

siona um aumento significativo do tamanho da aplicacao Java ME, pois esta tem que

incluir em seu pacote as classes da Bouncy Castle utilizadas.

Outra desvantagem e o fato de nao dar suporte ao uso de smart cards, alem

de carecer de uma documentacao eficaz, principalmente no ambito do pacote para Java

ME (lightweight).

3.3 Fundamentos de Criptografia

3.3.1 Introducao

A palavra criptografia surgiu da fusao das palavras gregas “kryptos” que

significa “oculto” e “graphein” que significa “escrever”. A criptografia trata-se de um

conjunto de conceitos e tecnicas que tem por objetivo codificar uma informacao de

forma que somente o emissor e o receptor possam ter acesso a mesma, dessa forma

evita que um intruso qualquer consiga interpreta-la. Para isso, uma serie de tecnicas

sao usadas e muitas outras surgem com o passar do tempo. [EME 05]

17

A mensagem original emitida e determinada de texto aberto. O texto aberto

e processado por um algoritmo de criptografia tornando-se um texto cifrado. O pro-

cesso de obtencao desse texto aberto original a partir do texto cifrado e denominado

decifragem. [ARA 02]

3.3.2 Criptografia Simetrica

Os algoritmos que se utilizam somente de uma chave tanto para o processo

de cifragem quanto para o de decifragem sao chamados de algoritmos criptograficos

simetricos. Esses algoritmos foram os primeiros a serem criados e sao muito utilizados

ate hoje para garantir o sigilo de informacoes. [DAV 09]

O funcionamento desse algoritmo se baseia no fato de ambos, transmissor

e receptor de alguma mensagem compartilharem uma mesma chave. Ou seja, uma

mensagem so pode ser decifrada pela mesma chave que foi utilizada para cifra-la.

Sendo assim, fica facil perceber que se receptor e transmissor, ambos tiverem

a chave e nao a compartilham com ninguem, somente eles podem entender a men-

sagem garantindo assim a privacidade e a autenticidade. Mas esse metodo apresenta

a desvantagem que e a troca da chave. Uma tarefa difıcil de manter o sigilo em um

grande ambiente como a Internet.

Abaixo esta uma ilustracao de como e realizada a criptografia simetrica:

Figura 3.1: Ilustracao do funcionamento da criptografia simetrica.

18

3.3.3 Criptografia Assimetrica

Tambem chamada de criptografia de chave publica, esse tipo de criptografia

proposto por Diffie e Hellman, e um sistema no qual e utilizado um par de chaves dis-

tintas tanto para cifrar quanto para decifrar. Normalmente uma delas e mantida em sig-

ilo, e recebe o nome de chave privada (KRa) e a outra e amplamente divulgada, sendo

denominada chave publica (KUa). O funcionamento ocorre da seguinte maneira: caso

se cifre a mensagem com a chave privada, ela so sera decifrada pela chave publica e

vice-versa.

Sendo assim, EKUAconsiste em aplicar o algoritmo de cifragem utilizando

a chave publica de uma entidade “A”, e DKRAresume-se na aplicacao do algoritmo

para decifrar a mensagem utilizando a chave privada de “A”. Isso considerando que

deve haver uma forte relacao entres as duas chaves citadas, de maneira a garantir que

DKRA(EKUA

(x)) = x. Como exemplos de cifradores assimetricos, podemos citar os

algoritmos RSA e ElGamal.

A criptografia assimetrica nao substitui a criptografia simetrica, pois os

algoritmos utilizados sao lentos e vulneraveis a alguns ataques. Normalmente se utiliza

a criptografia de chave publica para distribuicao com seguranca de chaves simetricas

(chaves de secao), pois estas serao utilizadas para a cifragem das mensagens.

Essa tecnica funciona da seguinte maneira: o transmissor gera uma chave

simetrica (chave de secao) e esta e cifrada usando a chave publica do receptor (chave

assimetrica) e depois a envia, apenas quem possuir a chave do receptor podera decifrar

o conteudo enviado. Recuperando assim a chave simetrica e ela entao podera ser usada

para a comunicacao. Esse modelo, tambem chamado de criptografia hıbrida, aproveita

as vantagens dos 2 modelos (simetrico e assimetrico). Abaixo ha uma figura ilustrando

essa tecnica:

19

Figura 3.2: Processo de criptografia e distribuicao da chave secreta na criptografia hıbrida.

3.4 ElGamal

Na criptografia, o sistema de criptografia ElGamal e um algoritmo de encrip-

tacao de chaves assimetricas baseada na troca de chaves de Diffie-Hellman. Foi de-

scrita em 1984 por Taher ElGamal. [WEE 11]

Este algoritmo permite confirmar a autenticidade de uma mensagem envi-

ada, mesmo que tenha sido enviada em um canal nao seguro, alem do fato de uso do

problema de logaritmo de algoritmo discreto. A geracao de suas chaves segue o padrao

das chaves publicas, ou seja, cada entidade gera um par de chaves e acertam a forma

como vao distribuir as chaves publicas.

A criptografia ElGamal consiste em tres componentes: A geracao de chaves,

a encriptacao e a decriptacao:

Geracao das Chaves

A entidade “A” procede do seguinte modo:

• Gera de forma aleatoria um numero primo p de grande dimensao e g, que e uma

raiz primitiva modulo p;

• Seleciona aleatoriamente um inteiro a, onde 1 ≤ a ≤ p-2 e calcula r = ga (mod

p);

20

• A chave publica da entidade sera (p, g, r), e sua chave privada sera a.

Encriptacao

• A entidade B obtem a chave publica de “A” (p, g, r);

• Representa a mensagem como se m fosse um inteiro no intervalo 0, 1, ..., p-1;

• Seleciona aleatoriamente um inteiro k, 1 ≤ k ≤ p-2;

• Calcula ψ = gk (mod p) e δ = m x rk (mod p);

• O texto cifrado sera c = (ψ, δ).

Decriptacao

Para haver a recuperacao, “A” deve:

• Usando a chave privada a, calcular ψ(p−1−a) (mod p);

• Recupera a mensagem m calculando ψ(−a) x δ (mod p).

O problema da cifra ElGamal e que ele possui um valor de expansao de

mensagem cifrada de 2, ou seja, o comprimento da mensagem cifrada e o dobro da

mensagem clara. O uso de aleatoriedade em seu codigo busca aumentar sua seguranca

ao evitar a eficiencia dos ataques atraves da analise estatıstica.

A seguranca do ElGamal esta baseada na dificuldade em se tirar logaritmos

discretos de numeros grandes, ou seja, de se obter a a partir de β, p e α (a = logα β

mod p). α e β devem ser grandes, alem disso, deve-se escolher um k diferente para

cada m. [ALI ]

21

3.5 Rede de Misturadores

Como definiu Araujo ([ARA 02], 2002, pag 25), sempre que se deseja uma

nao ligacao entre emissor e receptor em uma determinada comunicacao, uma rede de

misturadores e uma ferramenta bastante apropriada. Em sıntese, um misturador alem

de encaminhar as mensagens que chegam, tambem esconde a relacao entre as men-

sagens que nele chegam e que dele saem. Isso acontece devido ao fato de o misturador,

agrupar um determinado numero de mensagens que chegam para ele e mistura-las antes

que sejam encaminhadas.

Tendo como intuito nao correlacionar as mensagens que chegam com as

mensagens que saem, todas as mensagens que serao embaralhadas, precisam serem

cifradas. De modo que cifragens sucessivas da mesma mensagem mostram diferentes

resultados. E imprescindıvel tambem que todas as mensagens possuam um tamanho

uniforme, para que nao seja possıvel estabelecer uma relacao entre a mensagem e o

seu respectivo tamanho. Tal propriedade pode ser solucionada atraves da adicao de

”enchimentos”aleatorios.

Para um grupo de usuarios se comunicando, a nao ligacao entre as men-

sagens dos mesmos e garantida, exceto para o proprio misturador. Tendo como obje-

tivo melhorar os resultados, ou seja, obter mais seguranca, uma rede de misturadores e

montada. Tal rede e montada a partir do cascateamento de varios misturadores.

Uma rede de misturadores envelopa as mensagens para que essas sejam

lidas apenas por misturadores dirigidos. Envelopes digitais sao abertos e o conteudo

obtido e misturado antes de ser encaminhado para o misturador seguinte que atuara da

mesma forma. A entrega da mensagem ao destino e feito pelo ultimo misturador do

cascateamento, logo apos efetuar a ultima mistura.

Utilizando uma rede de misturadores, somente um unico misturador pre-

cisa ser honesto para prevenir os outros misturadores de nao quebrar a ligacao entre

origem e destino. O protocolo Farnel (2001, apud [ARA 02], 2002, p. 24) e um ex-

emplo de protocolo de votacao digital segura que utiliza este recurso criptografico.

22

Abaixo e apresentada uma figura que ilustra o funcionamento da rede:

Figura 3.3: Ilustracao mostrando embaralhamento das mensagens em cada um dos nodos da

rede.

Capıtulo 4

Prototipo do Sistema de Votacao em

Dispositivos Moveis

Neste capıtulo sera apresentado o prototipo de um sistema de votacao para

dispositivos moveis e suas funcionalidades, mostrando uma visao geral do sistema

com os requisitos, casos de uso e diagramas necessarios alem dos fluxos de trabalhos.

Tambem serao apresentados os resultados obtidos na votacao programada.

4.1 Preparacao do ambiente

Antes de iniciar uma eleicao e necessario preparar o ambiente e as configura-

coes para a votacao. Um dos principais requisitos de seguranca e a comunicacao segura

entre o cliente(votante) e o servidor que armazena os votos, para isso foi utilizado uma

implementacao da rede de misturadores de Chaum, desenvolvida pelo Laboratorio de

Seguranca em Computacao da Universidade Federal de Santa Catarina e denominado

JMixNet.

A rede de mistura foi criada em um ambiente virtual com 3 nodos (servi-

dores/misturadores) em decorrencia de simplicidade e tambem devido a dificuldade da

alocacao de um maior numero de servidores. A criacao de cada servidor da rede de

misturadores da jmixnet, assim como a forma de inicializar a rede pode ser encontrada

24

no apendice deste trabalho B.

Os outros 2 modulos importantes no trabalho sao o servidor, responsavel

por guardar os dados da eleicao e o cliente (ambiente que realizacao a votacao propri-

amente dita):

• O ambiente do servidor, necessita apenas de um certificado assinado pela autori-

dade certificadora da JMixNet, para rodar o modulo servidor “JmixnetServer”da

jmixnet alem do java jdk instalado. A instalacao do certificado assinado pode ser

encontrada no apendice B, assim como a instalacao do jdk pode ser encontrada

no apendice B;

• O ambiente onde foi desenvolvido o aplicativo cliente necessita apenas do J2ME

instalado, que pode ser encontrado no apendice B.

4.2 Prototipo Votacao

Para o projeto da aplicacao foram definidos os requisitos, a arquitetura, os

casos de uso e diagramas UML apresentados nas secoes subsequentes, a ultima secao

trata da apresentacao desenvolvida.

Requisitos Funcionais Cliente

• O software deve poder ser usado em uma ou mais eleicoes;

• O software deve fazer uso de uma rede de misturadores;

• O software deve ser compatıvel com a tecnologia MIDP 2.0;

• O software deve ser compatıvel com a tecnologia CLDC;

• O software devera usar a plataforma Java ME.

25

Requisitos Nao Funcionais Cliente

• O tempo de resposta do sistema nao deve ultrapassar 30 segundos;

• O software do sistema deve ser operacionalizado sobre qualquer sistema opera-

cional que suporte java (Padro j2me);

• O usuario devera fornecer informacoes como login e senha para autenticar-se;

• O usuario do sistema (modulo cliente), deve possuir um dispositivo com suporte

a java, atraves do qual ira realizar votacao;

• O voto deve ser cifrado usando o NIP (PIN) e a chave publica importada do

servidor;

• O cliente devera ler arquivos no formato de arquivo xml;

• O cliente devera ser capaz de cifrar votos utilizando o algoritmo de encriptacao

El-Gamal.

Requisitos Funcionais Servidor

• O software deve possibilitar a realizacao de uma ou mais votacoes;

• Os usuarios devem poder visualizar o resultado da apuracao de votos;

• Banco de dados Relacional;

• Navegador web;

• Sistema operacional.

Requisitos Nao Funcionais Servidor

• A base de dados deve ser protegida para acesso apenas de usuarios autorizados;

• O tempo de resposta do sistema nao deve ultrapassar 30 segundos;

26

• O software do sistema deve ser operacionalizado sobre qualquer sistema opera-

cional que suporte java(Padrao j2se);

• Acessıvel via web, utilizando paginas jsp;

• O usuario devera fornecer informacoes como login e senha para autenticar-se;

• O cliente devera ser capaz de decifrar votos utilizando o algoritmo de decifragem

El-Gamal;

• O software devera ser capaz de gerar pares de chaves com o algoritmo El-Gamal.

4.2.1 Arquitetura

O desenvolvimento da aplicacao foi baseado na comunicacao cliente (aplica-

tivo movel) - rede de misturadores - servidor , onde o cliente se comunica com a rede

de misturadores atraves do cliente da rede de mistura, enviando o voto para a rede e

a rede de misturadores envia o voto para o servidor jmixnet que recebe os votos e os

envia para o servidor final que armazena os votos. Os detalhes a arquitetura de cada

parte do prototipo pode ser vista abaixo.

4.2.1.1 Cliente - Dispositivo Movel

A arquitetura utilizado no cliente foi o MVC - Model-View-Controller que

divide a aplicacao em 3 partes basicas:

• Modelo - parte responsavel pela logica da aplicacao, onde fica a parte do codigo

que transforma os dados de entrada em resultados;

• Controle - parte responsavel por ligar a logica a interface;

• Visao - parte responsavel pela interface com o usuario.

27

4.2.1.2 Misturadores

Os misturadores da rede tem a funcao de receber as mensagens(votos)

guarda-los por um perıodo de tempo, embaralha-los e entao envia-los ao proximo mis-

turador da rede ou ao destino final, caso seja o ultimo misturador. O objetivo por tras

disso e quebrar a ligacao que ha entre quem envia e quem recebe uma mensagem, ou

seja retirar a ligacao do votante com o servidor que armazena os votos, garantindo

assim maior seguranca ao votante.

A rede de misturadores implementada para o projeto foi criada em um am-

biente virtual com 3 nodos(misturadores). O misturador 1 e responsavel por receber

as mensagens dos clientes(aplicativos moveis). Todos os votos enviados dos disposi-

tivos moveis sao direcionados somente para o misturador 1, atraves do JMixNetClient

(cliente da rede de misturadores) que esta embutido dentro da aplicacao cliente(dispositivo

movel que ira votar). Apos guardar por um tempo e acumular determinada quantidade

de mensagens, o misturador embaralha e envia as mensagens para o segundo mistu-

rador, que por sua vez realiza o mesmo processo (acumulo de mensagens e embaral-

hamento) e em seguida envia para o misturador 3. O misturador 3 e o ultimo nodo da

rede, responsavel por enviar os votos para o servidor final, que sera responsavel por

armazenar os votos.

Os detalhes da implementacao da rede de misturadores jmixnet pode ser

encontrada na tese de mestrado de Fabiano Castro Pereira ([FAB 05], 2005).

4.2.1.3 Servidor

O Servidor que armazena os votos assim como o cliente trabalha no padrao

MVC - Model-View-Controller, ja explicado acima.

4.2.2 Casos de Uso

Os casos de uso descritos abaixo foram elaborados a partir dos requisitos

descritos acima.

28

4.2.2.1 Casos de Uso Servidor

Cadastrar

Cadastrar Eleicao

1. O gerente do sistema acessa no menu a opcao de cadastro e seleciona o item

Cadastro de Eleicao.

2. O sistema exibe o formulario de cadastro de eleicao, onde alguns campos com

asteriscos sao considerados de carater obrigatorio: nome, data inicial, data final.

3. O gerente do sistema tera acesso aos botoes: Salvar e Cancelar.

4. O gerente do sistema preenche os dados.

5. O gerente do sistema clica no botao cancelar.

6. O gerente do sistema clica no botao salvar.

Tratamento de excecoes:

• 6a. Ja existe uma eleicao cadastrada com esse nome.

1. O sistema ira voltar a tela de cadastro para que o gerente do sistema modi-

fique o nome da eleicao a ser cadastrada.

2. O gerente do sistema digita um novo nome de eleicao.

3. Retorna ao fluxo principal no passo 4.

• 6b. O perıodo escolhido (data inicial e data final) sao incompatıveis.

1. O sistema exibe uma mensagem para o gerente de que o perıodo sele-

cionado e incompatıvel (data inicial posterior a final ou datas anteriores

a data corrente).

2. O sistema ira voltar a tela de cadastro para que o gerente do sistema modi-

fique o perıodo da eleicao a ser cadastrada.

29

3. O gerente do sistema seleciona um novo perıodo (data inicial ou final).

4. Retorna ao fluxo principal no passo 4.

Cadastrar Disputa

1. O gerente do sistema acessa no menu a opcao de cadastro e seleciona o item

Cadastro de Disputa.

2. O sistema exibe o formulario de cadastro de disputa, onde alguns campos com

asteriscos sao considerados de carater obrigatorio: nome.

3. O gerente do sistema tera acesso aos botoes: Salvar e Cancelar.

4. O gerente do sistema preenche os dados.

5. O gerente do sistema clica no botao cancelar.

6. O gerente do sistema clica no botao salvar.

Tratamento de excecoes:

• 6a. Ja existe uma disputa cadastrada com esse nome.

1. O sistema ira voltar a tela de cadastro para que o gerente do sistema modi-

fique o nome da disputa a ser cadastrada.

2. O gerente do sistema digita um novo nome de disputa.

3. Retorna ao fluxo principal no passo 4.

30

Cadastrar Candidato

1. O gerente do sistema acessa no menu a opcao de cadastro e seleciona o item

Cadastro de Candidato.

2. O sistema exibe o formulario de cadastro de candidato, onde alguns campos com

asteriscos sao considerados de carater obrigatorio: *nome, codigo, foto, disputa.

3. O gerente do sistema tera acesso aos botoes: Salvar e Cancelar.

4. O gerente do sistema preenche os dados.

5. O gerente do sistema clica no botao cancelar.

6. O gerente do sistema clica no botao salvar.

Tratamento de excecoes:

• 6a. Ja existe um candidato cadastrado com esse codigo para essa disputa.

1. O sistema ira voltar a tela de cadastro para que o gerente do sistema modi-

fique o codigo do candidato a ser cadastrado.

2. O gerente do sistema digita um novo codigo de candidato.

3. Retorna ao fluxo principal no passo 4.

Cadastrar Votante

1. O gerente do sistema acessa no menu a opcao de cadastro e seleciona o item

Cadastro de Votante.

2. O sistema exibe o formulario de cadastro de votante, onde alguns campos com

asteriscos sao considerados de carater obrigatorio: nome, identificacao, tipo de

identificacao, login, senha, certificado digital.

3. O gerente do sistema tera acesso aos botoes: Salvar e Cancelar.

31

4. O gerente do sistema preenche os dados.

5. O gerente do sistema clica no botao cancelar.

6. O gerente do sistema clica no botao salvar.

Tratamento de excecoes:

• 6a. Ja existe uma votante cadastrado com essa identificacao para esse tipo de

identificacao.

1. O sistema ira voltar a tela de cadastro para que o gerente do sistema modi-

fique o dado no campo identificacao do votante a ser cadastrado.

2. O gerente do sistema digita um novo dado para o campo identificacao do

votante.

3. Retorna ao fluxo principal no passo 4.

• 6b. Ja existe uma votante cadastrado com esse login.

1. O sistema ira voltar a tela de cadastro para que o gerente do sistema modi-

fique o dado no campo login do votante a ser cadastrado.

2. O gerente do sistema digita um novo dado para o campo login do votante.

3. Retorna ao fluxo principal no passo 4.

• 6c. Ja existe um votante cadastrado com esse certificado digital.

1. O sistema ira voltar a tela de cadastro para que o gerente do sistema faca o

upload de outro certificado digital para o votante a ser cadastrado.

2. O gerente do sistema faz o upload de outro certificado digital para o campo

certificado digital do votante.

3. Retorna ao fluxo principal no passo 4.

32

Remover

Remover Eleicao

1. O gerente do sistema acessa no menu a opcao de administracao e seleciona o

item Remover Eleicao.

2. O sistema gera uma listagem de eleicoes e um campo check ao lado de cada

eleicao.

3. O gerente do sistema tera acesso aos botoes: Remover e Cancelar.

4. O gerente do sistema seleciona a eleicao que deseja remover.

5. O gerente do sistema clica no botao cancelar.

6. O gerente do sistema clica no botao remover.

7. O sistema exibe os dados da eleicao numa nova tela, na qual exibe 2 botoes, para

que o usuario confirme a exclusao.

8. Apos confirmada a exclusao, todos os dados pertencentes a essa eleicao (dis-

putas, candidatos, votantes cadastrados) sao excluıdos.

Tratamento de excecoes:

• 6a. O usuario nao selecionou nenhuma eleicao.

1. O sistema ira voltar a tela de remocao para que o gerente do sistema sele-

cione uma eleicao que deseja remover.

2. Retorna ao fluxo principal no passo 4.

33

Remover Disputa

1. O gerente do sistema acessa no menu a opcao de administracao e seleciona o

item Remover Disputa.

2. O sistema gera uma listagem de disputas e um campo check ao lado de cada

disputa.

3. O gerente do sistema tera acesso aos botoes: Remover e Cancelar.

4. O gerente do sistema seleciona a disputa que deseja remover.

5. O gerente do sistema clica no botao cancelar.

6. O gerente do sistema clica no botao remover.

7. O sistema exibe os dados da disputa numa nova tela, na qual exibe 2 botoes, para

que o usuario confirme a exclusao.

8. Apos confirmada a exclusao, todos os dados pertencentes a essa disputa sao

excluıdos.

Tratamento de excecoes:

• 6a. O usuario nao selecionou nenhuma disputa.

1. O sistema ira voltar a tela de remocao para que o gerente do sistema sele-

cione uma disputa que deseja remover.

2. Retorna ao fluxo principal no passo 4.

34

Remover Candidato

1. O gerente do sistema acessa no menu a opcao de administracao e seleciona o

item Remover Candidato.

2. O sistema uma gera listagem de disputas e um campo check ao lado de cada

candidato.

3. O gerente do sistema tera acesso aos botoes: Remover e Cancelar.

4. O gerente do sistema seleciona o candidato que deseja remover.

5. O gerente do sistema clica no botao cancelar.

6. O gerente do sistema clica no botao remover.

7. O sistema exibe os dados do candidato numa nova tela, na qual exibe 2 botoes,

para que o usuario confirme a exclusao.

8. Apos confirmada a exclusao, todos os dados pertencentes a esse candidato sao

excluıdos.

Tratamento de excecoes:

• 6a. O usuario nao selecionou nenhum candidato.

1. O sistema ira voltar a tela de remocao para que o gerente do sistema sele-

cione um candidato que deseja remover.

2. Retorna ao fluxo principal no passo 4.

35

Remover Votante

1. O gerente do sistema acessa no menu a opcao de administracao e seleciona o

item Remover Votante.

2. O sistema gera uma listagem de disputas e um campo check ao lado de cada

votante.

3. O gerente do sistema tera acesso aos botoes: Remover e Cancelar.

4. O gerente do sistema seleciona o candidato que votante que deseja remover.

5. O gerente do sistema clica no botao cancelar.

6. O gerente do sistema clica no botao remover.

7. O sistema exibe os dados do votante numa nova tela, na qual exibe 2 botoes, para

que o usuario confirme a exclusao.

8. Apos confirmada a exclusao, todos os dados pertencentes a esse votante sao

excluıdos.

Tratamento de excecoes:

• 6a. O usuario nao selecionou nenhum votante.

1. O sistema ira voltar a tela de remocao para que o gerente do sistema sele-

cione um votante que deseja remover.

2. Retorna ao fluxo principal no passo 4.

4.2.3 Diagramas

Abaixo sao apresentados os casos separados entre casos de uso do Admi-

nistrador/gerenciador do sistema, responsavel por criar a eleicao e configura-la, e os

casos de uso do votante.

36

4.2.3.1 Diagrama de casos de uso do Administrador

Figura 4.1: Casos de Uso Servidor

4.2.3.2 Diagrama de casos de uso do Votante

Figura 4.2: Casos de Uso Votante

37

4.2.4 Apresentacao da Aplicacao

Fase de Configuracao

A aplicacao se divide em 2 grandes partes. A primeira e a fase de configuracao,

onde o administrador da votacao cadastra os votantes, os candidatos, a eleicao , as dis-

putas e todos os parametros necessarios para a eleicao como data de inicio, data de

termino, data para apresentacao dos resultados, como mostrado abaixo.

A tela inicial que o administrador tem acesso apos fazer login e a tela de

gerencia onde ele tem acesso aos recursos de listagem, cadastro, remocao de todos os

recursos relacionados a votacao. abaixo sera mostrado exemplos da visao do admin-

istrador do sistema.

Tela Principal

Nessa tela aparece as opcoes disponıveis para o perfil administrador do

sistema, alem da listagem das votacoes pendentes(ainda nao iniciadas) e votacoes em

andamento.

Figura 4.3: Tela Inicial

38

Cadastros

O administrador pode criar eleicao. A eleicao e a parte central do prototipo

a ela esta vinculada as disputadas que representao o objeto da votacao.

A tela de cadastro de eleicao possui cinco campos,(nome,data de inicio,

data de termino,tipo de autenticacao, status). O campo nome e identificante, para nao

haver confusao na hora do voto, a data de inicio e data de fim, servem respectiva-

mente para delimitar o tempo em que a votacao podera ser executada,o campo tipo de

autenticacao define a forma como os votantes podem logar no sistema, para o prototipo

foi definido apenas login/senha mas o ambiente esta preparado para suportar outras for-

mas de autenticacao como certificado digital.

Abaixo e mostrado a tela de cadastro da eleicao:

Figura 4.4: Cadastro Eleicao

39

Os outros cadastros disponıveis para o administrador sao o cadastro de

disputadas onde e mostrado um campo de escolha de eleicao, para ser cadastrado uma

disputa vinculada a eleicao escolhida,o campo nome e descricao da disputa sao campos

de texto simples onde o administrador determina os parametros da disputa.

O cadastro de votante possui os campos nome,data de nascimento e cpf,

que sao os dados pessoais de cada votante, alem dos campos de login, senha e o NIP

(PIN) do celular que sao usados para logar no sistema, o NIP (PIN) e o numero de

identificacao do celular, que e usado para o votante poder votar somente no celular

pre-cadastrado.

O cadastro do candidato possui os campos de nome (nome do candidato),

codigo que e utilizado para votacao por codigo, quando a eleicao estiver definida como

codigo um campo de foto, e os campos de combo para selecionar a disputa e a eleicao

ao qual o candidato esta vinculado.

Alem dos cadastros o administrador do sistema, pode visualizar os dados,

atraves das listagens, a listagem de eleicoes ativas esta disponıvel na tela inicial, para

as listagens de disputas e votantes ha uma sessao separada no menu, nessas listagens

tambem e possıvel remover a entidade listada.

Abaixo sao mostradas 2 telas, uma tela de referencia para a visualizacao

de cadastro e uma para visualizacao de como e exibida a listagem, demais telas podem

ser encontradas em anexo:

40

Figura 4.5: Cadastro do Votante

Figura 4.6: Listagem das Disputas

41

Fase de Votacao

A segunda fase do processo de votacao implementado e onde ha a escolha

do voto de cada um dos votantes do processo de votacao. A seguir sera apresentado o

fluxo principal da escolha dos candidatos no cliente. A tela inicial que o votante tem

acesso, ao iniciar a aplicacao e a tela de login, na qual o votante insere seus dados de

login e senha, previamente cadastrados no servidor. Se o votante conseguir logar rece-

bera do servidor uma lista de disputas no qual ele esta vinculado, juntamente com os

candidatos de cada uma dessas disputas e tambem recebera a chave publica (ElGamal)

do servidor que sera usada para cifrar o voto.

Figura 4.7: Login

Apos o login, e exibido ao votante a tela de escolha do candidato, nessa

tela uma disputa ao qual o votante ainda nao votou e escolhida, se a eleicao estiver

configurada para exibicao das disputas por listagem e exibida uma lista com todos os

votantes da disputa escolhida.

42

Figura 4.8: Escolha do candidato com listagem

Se for configurada a exibicao por codigo e exibida uma tela indicando a

disputa escolhida e um campo para o votante digitar o codigo do candidato.

Figura 4.9: Escolha do candidato por codigo

Apos a escolha do candidato deseja e apresentada uma tela de confirmacao

com os dados do candidato escolhido a disputa ao qual ele pertence, e dois botoes um

com a opcao de confirmar o voto no candidato, e outro com a opcao de cancelar, se can-

43

celado o voto, a aplicacao volta para a tela anterior para o votante escolher novamente

o candidato da disputa.

Se o votante clicar em confirmar o voto uma nova disputa em que o votante

nao votou ainda e escolhida e e apresentado novamente a tela de escolha do candidato.

Caso o votante essa seja a ultima disputa que a ser votada e exibida a tela de termino

da votacao, se o votante logar e ja tiver votado em todas as disputas essa mesma tela

tambem e apresentada.

Figura 4.10: Escolha do candidato por codigo

44

Fluxo de Votacao

Figura 4.11: Fluxo de votacao

Capıtulo 5

Conclusao

46

Referencias

[ALI ] ALINE SOUSA DA SILVEIRA e ANTONIO CANDIDO FALEIROS.

CRIPTOGRAFIA DE CHAVE PUBLICA - O PAPEL DA ARITMETICA EM

PRECISAO MULTIPLA. Disponıvel em

<http://www.bibl.ita.br/xiencita/Artigos/Fund05.pdf>. Acesso em: 16 de maio de 2011.

[AND 07] ANDRE LUIZ CARDOSO. Uma ferramenta para obtencao on line de certificados

digitais para uso de smart cards em aplicacoes Java ME. Disponıvel em

<http://www.projetos.inf.ufsc.br/arquivos projetos/projeto 582/tcc.pdf.1>. Acesso em: 16

de maio de 2011.

[ARA 02] ARAUJO, R. S. D. S. Protocolos Criptograficos para Votacao Digital. Universidade

Federal de Santa Catarina, 2002. Curso de pos-graduacao em ciencia da computacao.

[CRI 11] CRISTIANO FIORESI. CONCEITOS BASICOS DAS PLATAFORMAS JAVA E

J2ME. Disponıvel em

<http://www.devmedia.com.br/articles/viewcomp forprint.asp?comp=6484>. Acesso em:

16 de maio de 2011.

[DAV 09] DAVI GARCIA PEREIRA. Assinatura Digital de Documentos Eletronicos em

Dispositivos Moveis. Disponıvel em

<http://www.projetos.inf.ufsc.br/arquivos projetos/projeto 692/tcc-davigp-final.pdf>.

Acesso em: 16 de maio de 2011.

[EME 05] EMERSON ALECRIM. Criptografia. Disponıvel em

<http://www.infowester.com/criptografia.php>. Acesso em: 16 de maio de 2011.

[FAB 05] FABIANO CASTRO PEREIRA. Estudo e Implementacao de Redes de Comunicacao

Anonima e aplicacao ao Sistema de Votacao Digital OSTRACON. Universidade

Federal de Santa Catarina, 2005. Curso de pos-graduacao em ciencia da computacao.

48

[JCP 11] JCP - Java Community Process. Community Development of Java Technology

Specifications. Disponıvel em <http://jcp.org/en/introduction/overview>. Acesso em: 16

de maio de 2011.

[LUI 06] LUIS MIGUEL SILVA COSTA e NUNO ALEXANDRE COSTA FRETA DOS SANTOS.

MobileREVS - Votacao Electronica. Disponıvel em

<http://www.gsd.inesc-id.pt/mrevs/MobileREVS RelatorioTFC.pdf>. Acesso em: 16 de

maio de 2011.

[POS 11] Sobre o PostgreSQL. Disponıvel em <http://www.postgresql.org.br/sobre>. Acesso em:

16 de maio de 2011.

[WEE 11] Site Wikipedia. ElGamal encryption. Disponıvel em

<http://en.wikipedia.org/wiki/ElGamal encryption>. Acesso em: 16 de maio de 2011.

[WES 11] Site Wikipedia. Eclipse (software). Disponıvel em

<http://en.wikipedia.org/wiki/Eclipse %28software%29>. Acesso em: 16 de maio de

2011.

Apendice A

Codigo Fonte

A.1 Servidor

package br.com.dao;

import java.util.List;

import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session;

import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration;

import org.hibernate.criterion.Expression;

import br.com.beam.Candidato; import br.com.beam.Voto;

public class CandidatoDAO

public CandidatoDAO()

private Session getSession() SessionFactory sf = new AnnotationConfigu-

ration().configure().buildSessionFactory(); Session session = sf.openSession(); return

session;

public void cadastrarCandidato(Candidato candidato) AnnotationConfig-

uration configuracao = new AnnotationConfiguration(); configuracao.addAnnotatedClass(Candidato.class);

configuracao.addAnnotatedClass(Voto.class); configuracao.configure(”hibernate.cfg.xml”);

//linha abaixo apenas descomentar se a tabela ainda nao existir //new SchemaEx-

port(configuracao).create(true, true); SessionFactory fabrica = configuracao.buildSessionFactory();

Session secao = fabrica.getCurrentSession(); secao.beginTransaction(); secao.save(candidato);

50

secao.getTransaction().commit();

public List¡Candidato¿ getTodosCandidatos() try Query query = this.getSession().createQuery(”from

Candidato c”); List¡Candidato¿ lista = (List¡Candidato¿) query.list(); return lista; catch

(Exception e) e.printStackTrace(); return null;

public Candidato getCandidatoPorCodigo(int codigoCandidato) Session

session = this.getSession(); Query query = session.getNamedQuery(”getCandidatoPorCodigo”);

query.setParameter(”codigo”, codigoCandidato); Candidato candidato = (Candidato)

query.uniqueResult(); return candidato;

package br.com.dao;

import java.util.List;

import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session;

import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration;

import org.hibernate.criterion.Expression;

import br.com.beam.Candidato; import br.com.beam.Disputa; import br.com.beam.Eleicao;

import br.com.beam.Voto;

public class DisputaDAO

public DisputaDAO()

private Session getSession() SessionFactory sf = new AnnotationConfigu-

ration().configure().buildSessionFactory(); Session session = sf.openSession(); return

session;

public void cadastraDisputa(Disputa disputa) AnnotationConfiguration con-

figuracao = new AnnotationConfiguration(); configuracao.addAnnotatedClass(Disputa.class);

configuracao.addAnnotatedClass(Voto.class); configuracao.configure(”hibernate.cfg.xml”);

//linha abaixo apenas descomentar se a tabela ainda nao existir //new SchemaEx-

port(configuracao).create(true, true); SessionFactory fabrica = configuracao.buildSessionFactory();

Session secao = fabrica.getCurrentSession(); secao.beginTransaction(); secao.save(disputa);

secao.getTransaction().commit();

@SuppressWarnings(”unchecked”) public List¡Disputa¿ getTodasDisputas()

try Query query = this.getSession().createQuery(”from Disputa d”); List¡Disputa¿ lista

51

= (List¡Disputa¿) query.list(); return lista; catch (Exception e) e.printStackTrace(); re-

turn null;

public Disputa getDisputaPorNome(String nomeDisputa) Session session

= this.getSession(); Query query = session.getNamedQuery(”getDisputaPorNome”);

query.setParameter(”nome”, nomeDisputa); Disputa disputa = (Disputa) query.uniqueResult();

return disputa;

@SuppressWarnings(”unchecked”) public List¡Disputa¿ getDisputasPorEle-

icao(Eleicao id) Session session = this.getSession(); Query query = session.getNamedQuery(”getDisputasPorEleicao”);

query.setParameter(”id”, id); List¡Disputa¿ listaDisputas = (List¡Disputa¿) query.list();

return listaDisputas;

package br.com.dao;

import java.util.List;

import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session;

import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration;

import org.hibernate.criterion.Expression; import org.hibernate.tool.hbm2ddl.SchemaExport;

import br.com.beam.Candidato; import br.com.beam.Disputa; import br.com.beam.Eleicao;

import br.com.beam.StatusEleicao; import br.com.beam.Votante; import br.com.beam.VotanteEleicao;

public class EleicaoDAO

public EleicaoDAO()

private Session getSession() SessionFactory sf = new AnnotationConfigu-

ration().configure().buildSessionFactory(); Session session = sf.openSession(); return

session;

public void cadastrarEleicao(Eleicao eleicao)

AnnotationConfiguration configuracao = new AnnotationConfiguration();

configuracao.addAnnotatedClass(Eleicao.class); configuracao.addAnnotatedClass(Votante.class);

configuracao.addAnnotatedClass(Disputa.class); configuracao.addAnnotatedClass(Candidato.class);

configuracao.configure(”hibernate.cfg.xml”); //linha abaixo apenas descomentar se a

tabela ainda nao existir if (this.getTodasEleicoes()==null) new SchemaExport(configuracao).create(true,

true); SessionFactory fabrica = configuracao.buildSessionFactory(); Session secao =

52

fabrica.getCurrentSession(); secao.beginTransaction(); secao.save(eleicao); secao.getTransaction().commit();

@SuppressWarnings(”unchecked”) public List¡Eleicao¿ getTodasEleicoes()

try Query query = this.getSession().createQuery(”from Eleicao e”); List¡Eleicao¿ lista

= (List¡Eleicao¿) query.list(); return lista; catch (Exception e) return null;

@SuppressWarnings(”unchecked”) public List¡Eleicao¿ getEleicaoDisponivel-

DoVotante(List¡Long¿ listaPassada) try String pedacoQuery = ; String andIdDif = ”and

e.id¡¿ ”; if (listaPassada.size()¿0) pedacoQuery = ”where e.id¡¿ ”+listaPassada.get(0).toString();

for (int i=1;i¡listaPassada.size();i++) pedacoQuery = pedacoQuery + andIdDif + listaPas-

sada.get(i).toString(); Query query = this.getSession().createQuery(”from Eleicao e

”+pedacoQuery); List¡Eleicao¿ lista = (List¡Eleicao¿) query.list(); return lista; catch

(Exception e) return null;

@SuppressWarnings(”unchecked”) public List¡Eleicao¿ getEleicaoPorSta-

tus(StatusEleicao status) Session session = this.getSession(); Query query = session.getNamedQuery(”getEleicaoPorStatus”);

query.setParameter(”status”, status); List¡Eleicao¿ listaEleicao = (List¡Eleicao¿) query.list();

return listaEleicao;

public Eleicao getEleicaoPorNome(String nomeEleicao) Session session

= this.getSession(); Query query = session.getNamedQuery(”getEleicaoPorNome”);

query.setParameter(”nome”, nomeEleicao); Eleicao eleicao = (Eleicao) query.uniqueResult();

return eleicao;

public Eleicao getEleicaoPorId(Long id) Session session = this.getSession();

Query query = session.getNamedQuery(”getEleicaoPorId”); query.setParameter(”id”,

id); Eleicao eleicao = (Eleicao) query.uniqueResult(); return eleicao;

package br.com.dao;

import org.hibernate.Session; import org.hibernate.SessionFactory; import

org.hibernate.cfg.AnnotationConfiguration;

import br.com.beam.PinEleicao;

public class PinEleicaoDAO

private Session getSession() SessionFactory sf = new AnnotationConfigu-

53

ration().configure().buildSessionFactory(); Session session = sf.openSession(); return

session;

public void cadastrarPinEleicao(PinEleicao pinEleicao) AnnotationCon-

figuration configuracao = new AnnotationConfiguration(); configuracao.addAnnotatedClass(PinEleicao.class);

configuracao.configure(”hibernate.cfg.xml”); //linha abaixo apenas descomentar se a

tabela ainda nao existir //new SchemaExport(configuracao).create(true, true); Session-

Factory fabrica = configuracao.buildSessionFactory(); Session secao = fabrica.getCurrentSession();

secao.beginTransaction();

secao.save(pinEleicao);

secao.getTransaction().commit();

package br.com.dao;

import java.util.List;

import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session;

import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration;

import org.hibernate.criterion.Expression;

import br.com.beam.Eleicao; import br.com.beam.Login Senha; import br.com.beam.Votante;

public class VotanteDAO

public VotanteDAO()

private Session getSession() SessionFactory sf = new AnnotationConfigu-

ration().configure().buildSessionFactory(); Session session = sf.openSession(); return

session;

public void cadastrarVotante(Votante votante) AnnotationConfiguration

configuracao = new AnnotationConfiguration(); configuracao.addAnnotatedClass(Votante.class);

configuracao.addAnnotatedClass(Login Senha.class); configuracao.configure(”hibernate.cfg.xml”);

//linha abaixo apenas descomentar se a tabela ainda nao existir //new SchemaEx-

port(configuracao).create(true, true); SessionFactory fabrica = configuracao.buildSessionFactory();

Session secao = fabrica.getCurrentSession(); secao.beginTransaction();

Login Senha loginSenha = votante.getFk login Senha(); loginSenha.setFk votante(votante);

votante.setFk login Senha(loginSenha); secao.save(votante); secao.save(loginSenha);

54

secao.getTransaction().commit();

public List¡Votante¿ getTodosVotantes() try Query query = this.getSession().createQuery(”from

Votante v”); List¡Votante¿ lista = (List¡Votante¿) query.list(); return lista; catch (Ex-

ception e) e.printStackTrace(); return null;

public Votante getVotantePorCodigo(int codigoVotante) Criteria consulta

= this.getSession().createCriteria(Votante.class); consulta.add( Expression.like(”codigo”,

codigoVotante) ); Votante votante = (Votante) consulta.uniqueResult(); return votante;

public Votante getVotantePorIdentificacao(String identificacao) Session ses-

sion = this.getSession(); Query query = session.getNamedQuery(”getVotantePorIdentificacao”);

query.setParameter(”identificacao”, identificacao); Votante votante = (Votante) query.uniqueResult();

return votante;

package br.com.dao;

import java.util.List;

import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session;

import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration;

import org.hibernate.criterion.Expression;

import br.com.beam.Eleicao; import br.com.beam.Login Senha; import br.com.beam.StatusEleicao;

import br.com.beam.Votante; import br.com.beam.VotanteEleicao;

public class VotanteEleicaoDAO

public VotanteEleicaoDAO()

private Session getSession() SessionFactory sf = new AnnotationConfigu-

ration().configure() .buildSessionFactory(); Session session = sf.openSession(); return

session;

public void cadastrarVotanteEleicao(VotanteEleicao votanteEleicao) An-

notationConfiguration configuracao = new AnnotationConfiguration(); SessionFactory

fabrica = configuracao.buildSessionFactory(); Session secao = fabrica.getCurrentSession();

secao.beginTransaction(); try configuracao.addAnnotatedClass(VotanteEleicao.class);

configuracao.configure(”hibernate.cfg.xml”); // linha abaixo apenas descomentar se

a tabela ainda nao existir // new SchemaExport(configuracao).create(true, true); se-

55

cao.save(votanteEleicao); secao.getTransaction().commit(); catch (Exception e) //

TODO: handle exception finally secao.close();

@SuppressWarnings(”unchecked”) public List¡VotanteEleicao¿ getEleicaoDoVotan-

tePorIdDoVotante(Votante id) Session session = this.getSession(); Query query = ses-

sion.getNamedQuery(”getVotanteEleicaoPorIdDoVotante”); query.setParameter(”id”,

id); List¡VotanteEleicao¿ listaEleicao = (List¡VotanteEleicao¿) query.list(); return lis-

taEleicao;

package br.com.dto;

import br.com.beam.Eleicao; import br.com.beam.Votante; import br.com.beam.VotanteEleicao;

public class VotanteEleicaoDTO

private Votante votante; private Eleicao eleicao;

public VotanteEleicao preencherVotanteEleicao(VotanteEleicao votanteEle-

icao) votanteEleicao.setVotante(getVotante()); //votanteEleicao.setEleicao(getEleicao());

return votanteEleicao;

public void preencherDTO(VotanteEleicao votanteEleicao) this.setEleicao(votanteEleicao.getEleicao());

//this.setVotante(votanteEleicao.getVotante());

public void setVotante(Votante votante) this.votante = votante;

public Votante getVotante() return votante;

public void setEleicao(Eleicao eleicao) this.eleicao = eleicao;

public Eleicao getEleicao() return eleicao;

package br.com.war;

import java.awt.image.BufferedImage; import java.io.BufferedInputStream;

import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream;

import java.util.ArrayList; import java.util.List;

import javax.faces.event.PhaseId; import javax.faces.event.ValueChangeEvent;

import javax.faces.model.SelectItem; import javax.imageio.ImageIO;

import org.apache.myfaces.custom.fileupload.UploadedFile;

import br.com.beam.Candidato; import br.com.beam.Disputa; import br.com.beam.Eleicao;

import br.com.dao.CandidatoDAO; import br.com.dao.DisputaDAO; import br.com.dao.EleicaoDAO;

56

import br.com.dto.CandidatoDTO;

public class CandidatoBB

private String nome; private int codigo; private CandidatoDAO candidato-

DAO; private Candidato candidato; private List¡SelectItem¿ listaDisputaExibir; private

String disputaSelecionada; private DisputaDAO disputaDAO; private List¡Disputa¿

listaDisputas; private transient UploadedFile uploadFoto; private CandidatoDTO can-

didatoDTO; private String eleicaoSelecionada; private List¡Eleicao¿ listaEleicoes; pri-

vate EleicaoDAO eleicaoDAO; private String codigoString;

public CandidatoBB() candidatoDAO = new CandidatoDAO(); candidato

= new Candidato(); disputaDAO = new DisputaDAO(); candidatoDTO = new Candida-

toDTO(); eleicaoDAO = new EleicaoDAO(); this.getListaEleicaoSelectItem(); this.getListaDisputaSelectItem();

public String cadastrarCandidato() Candidato candidatoBanco = candida-

toDAO.getCandidatoPorCodigo(this .getCodigo()); String retorno = ; if (candidato-

Banco == null) candidato.setNome(this.getNome()); candidato.setCodigo(Integer.parseInt(this.getCodigoString()));

candidato.setDisputa(disputaDAO .getDisputaPorNome(this.disputaSelecionada)); can-

didatoDAO.cadastrarCandidato(candidato); retorno = ”candidatoCadastrado”; else

retorno = ”erroCodigoCandidato”; return retorno;

public String voltarPaginaInicial() return ”voltar”;

public void paintImage(OutputStream os, Object data) throws IOExcep-

tion BufferedImage img = ImageIO.read(new BufferedInputStream( new ByteArray-

InputStream(this.candidatoDTO.getFoto()))); ImageIO.write(img, ”jpeg”, os);

public List¡SelectItem¿ getListaDisputaSelectItem() List¡SelectItem¿ lis-

taSelectItem = new ArrayList¡SelectItem¿(); Eleicao eleicao; if (this.getEleicaoSelecionada()

!= null) eleicao = eleicaoDAO.getEleicaoPorNome(this.getEleicaoSelecionada()); else

eleicao = eleicaoDAO.getTodasEleicoes().get(0); listaDisputas = disputaDAO.getDisputasPorEleicao(eleicao);

for (int i = 0; i ¡ listaDisputas.size(); i++) listaSelectItem.add(new SelectItem(listaDisputas.get(i).getNome()));

return listaSelectItem;

public List¡SelectItem¿ getListaEleicaoSelectItem() List¡SelectItem¿ lis-

57

taSelectItem = new ArrayList¡SelectItem¿(); listaEleicoes = eleicaoDAO.getTodasEleicoes();

for (int i=0;i¡listaEleicoes.size();i++) listaSelectItem.add(new SelectItem(listaEleicoes.get(i).getNome()));

return listaSelectItem;

public void selecionarEleicao(ValueChangeEvent evt) if (evt.getPhaseId().equals(PhaseId.ANY PHASE))

evt.setPhaseId(PhaseId.UPDATE MODEL VALUES); evt.queue(); if (evt.getPhaseId().equals(PhaseId.UPDATE MODEL VALUES))

if (this.getEleicaoSelecionada() != null) this.setEleicaoSelecionada(this.eleicaoSelecionada);

public String getNome() return nome;

public void setNome(String nome) this.nome = nome;

public int getCodigo() return codigo;

public void setCodigo(int codigo) this.codigo = codigo;

public void setListaDisputaExibir(List¡SelectItem¿ listaDisputaExibir) this.listaDisputaExibir

= listaDisputaExibir;

public List¡SelectItem¿ getListaDisputaExibir() return listaDisputaExibir;

public void setDisputaSelecionada(String disputaSelecionada) this.disputaSelecionada

= disputaSelecionada;

public String getDisputaSelecionada() return disputaSelecionada;

public void setUploadFoto(UploadedFile uploadFoto) throws IOException

this.candidatoDTO.setFoto(uploadFoto.getBytes()); this.uploadFoto = uploadFoto;

public UploadedFile getUploadFoto() return this.uploadFoto;

public void setEleicaoSelecionada(String eleicaoSelecionada) this.eleicaoSelecionada

= eleicaoSelecionada;

public String getEleicaoSelecionada() return eleicaoSelecionada;

public void setCodigoString(String codigoString) this.codigoString = codigoString;

public String getCodigoString() return codigoString;

package br.com.war;

import java.util.ArrayList; import java.util.List;

58

import javax.faces.context.FacesContext; import javax.faces.model.SelectItem;

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession;

import br.com.beam.Eleicao; import br.com.beam.Votante; import br.com.beam.VotanteEleicao;

import br.com.dao.EleicaoDAO; import br.com.dao.VotanteDAO; import br.com.dao.VotanteEleicaoDAO;

import br.com.dto.VotanteEleicaoDTO;

public class VotanteEleicaoBB

private Eleicao eleicao; private Votante votante; private VotanteEleicao

votanteEleicao; private VotanteEleicaoDAO votanteEleicaoDAO; private EleicaoDAO

eleicaoDAO; private String eleicaoSelecionada; private VotanteEleicaoDTO votanteEle-

icaoDTO; private String valorCPF; private VotanteDAO votanteDAO; private boolean

votanteExiste = false;

public VotanteEleicaoBB() votanteEleicaoDAO = new VotanteEleicao-

DAO(); eleicaoDAO = new EleicaoDAO(); votanteEleicao = new VotanteEleicao();

votanteDAO = new VotanteDAO(); setVotanteEleicaoDTO(new VotanteEleicaoDTO());

public String cadastrarVotanteEleicao() votanteEleicao.setEleicao(eleicaoDAO.getEleicaoPorNome(this.getEleicaoSelecionada()));

votanteEleicao.setVotante(this.votante); votanteEleicaoDAO.cadastrarVotanteEleicao(votanteEleicao);

return ”votanteEleicaoCadastrado”;

public List¡Eleicao¿ getListaEleicaoDoVotanteEleicaoEmQueOVotanteNaoEs-

taContido() if (votante!=null) Long id = votante.getId(); setVotanteExiste(true);

List¡VotanteEleicao¿ listaVotanteEleicao = votanteEleicaoDAO.getEleicaoDoVotantePorIdDoVotante(votante);

List¡Long¿ listaDeIdDasEleicoesQueOVotanteEstaCadastrado = new ArrayList¡Long¿();

if (listaVotanteEleicao!=null) for (int i=0;i¡listaVotanteEleicao.size();i++) listaDeId-

DasEleicoesQueOVotanteEstaCadastrado.add(i, listaVotanteEleicao.get(i).getEleicao().getId());

else

return eleicaoDAO.getEleicaoDisponivelDoVotante(listaDeIdDasEleicoesQueOVotanteEstaCadastrado);

public String buscarVotantePorCPF() this.setVotante(votanteDAO.getVotantePorIdentificacao(this.getValorCPF()));

this.getListaEleicaoSelectItem(); return ”buscarVotantePorCPFSucesso”;

public List¡SelectItem¿ getListaEleicaoSelectItem() List¡SelectItem¿ lis-

59

taSelectItem = new ArrayList¡SelectItem¿(); List¡Eleicao¿ listaEleicoesDisponiveis =

this.getListaEleicaoDoVotanteEleicaoEmQueOVotanteNaoEstaContido(); for (int i=0;i¡listaEleicoesDisponiveis.size();i++)

listaSelectItem.add(new SelectItem(listaEleicoesDisponiveis.get(i).getNome())); re-

turn listaSelectItem;

public void setEleicaoSelecionada(String eleicaoSelecionada) this.eleicaoSelecionada

= eleicaoSelecionada;

public String getEleicaoSelecionada() return eleicaoSelecionada;

public void setEleicao(Eleicao eleicao) this.eleicao = eleicao;

public Eleicao getEleicao() return eleicao;

public void setVotante(Votante votante) this.votante = votante;

public Votante getVotante() return votante;

public void setVotanteEleicaoDTO(VotanteEleicaoDTO votanteEleicaoDTO)

this.votanteEleicaoDTO = votanteEleicaoDTO;

public VotanteEleicaoDTO getVotanteEleicaoDTO() return votanteEle-

icaoDTO;

public void setValorCPF(String valorCPF) this.valorCPF = valorCPF;

public String getValorCPF() return valorCPF;

public void setVotanteExiste(boolean votanteExiste) this.votanteExiste =

votanteExiste;

public boolean isVotanteExiste() return votanteExiste;

package br.com.war;

import java.util.ArrayList; import java.util.Date; import java.util.List;

import javax.faces.context.FacesContext; import javax.faces.model.SelectItem;

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession;

import br.com.beam.Eleicao; import br.com.beam.login Senha; import br.com.beam.StatusVotante;

import br.com.beam.TipoIdentificacao; import br.com.beam.Votante; import br.com.dao.EleicaoDAO;

import br.com.dao.VotanteDAO; import br.com.dto.VotanteEleicaoDTO;

public class VotanteBB

private String nome; private Date dataNascimento; private String identi-

60

ficacao; private TipoIdentificacao tipoIdentificacao; private StatusVotante status; pri-

vate String senha; private String valorPin; private VotanteDAO votanteDAO; private

Votante votante; private String tipoIdentSelecionada; private String statusSelecionado;

private EleicaoDAO eleicaoDAO; private String login; private VotanteEleicaoDTO

votanteEleicaoDTO;

public VotanteBB() votanteDAO = new VotanteDAO(); votante = new

Votante(); votanteEleicaoDTO = new VotanteEleicaoDTO();

public String cadastrarVotante() login Senha loginSenha = new login Senha();

loginSenha.setLogin(this.getLogin()); loginSenha.setSenha(this.getSenha()); votante.setNome(this.getNome());

votante.setDataNascimento(this.getDataNascimento()); votante.setIdentificacao(this.getIdentificacao());

votante.setStatus(status.NAO VOTOU); //this.selecionaTipoIdentificacao(); votante.setTipoIdentificacao(tipoIdentificacao.CPF);

votante.setFk login Senha(loginSenha); votante.setValorPin(this.getValorPin()); votanteDAO.cadastrarVotante(votante);

FacesContext context = FacesContext.getCurrentInstance(); HttpServle-

tRequest myRequest = (HttpServletRequest)context.getExternalContext().getRequest();

HttpSession mySession = myRequest.getSession(); String atributo = (String) mySes-

sion.getAttribute(”identificacaoVotante”); String parametro = myRequest.getParameter(”identificacaoVotante”);

String identificacao = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(”identificacaoVotante”);

String temp[] = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterValuesMap().get(”identificacaoVotante”);

for (int i=0;i¡temp.length;i++) votanteEleicaoDTO.setVotante(votante); return ”votan-

teCadastrado”;

public Eleicao retornaPrimeiraEleicaoCriada() eleicaoDAO = new Ele-

icaoDAO(); return eleicaoDAO.getTodasEleicoes().get(0);

public void selecionaStatus() if (statusSelecionado.equalsIgnoreCase(”0”))

votante.setStatus(StatusVotante.NAO AUTORIZADO); else if (statusSelecionado.equalsIgnoreCase(”1”))

votante.setStatus(StatusVotante.NAO VOTOU); else if (statusSelecionado.equalsIgnoreCase(”2”))

votante.setStatus(StatusVotante.JA VOTOU);

public void selecionaTipoIdentificacao() if (tipoIdentSelecionada.equalsIgnoreCase(”0”))

votante.setTipoIdentificacao(TipoIdentificacao.RG); else if (tipoIdentSelecionada.equalsIgnoreCase(”1”))

votante.setTipoIdentificacao(TipoIdentificacao.CPF); else votante.setTipoIdentificacao(TipoIdentificacao.NUMERO AUTORIDADE);

61

public List¡String¿ listaTipoIdentificacao() List¡String¿ listaTipoIdent =

new ArrayList¡String¿(); for (int i = 0; i ¡ 3; i++) listaTipoIdent.add( + i); return

listaTipoIdent;

public List¡SelectItem¿ getListaTipoIdentificacao() List¡SelectItem¿ lis-

taSelectItem = new ArrayList¡SelectItem¿(); for (int i = 0; i ¡ this.listaTipoIdentificacao().size();

i++) listaSelectItem .add(new SelectItem(listaTipoIdentificacao().get(i)));

return listaSelectItem;

public List¡String¿ listaStatusString() List¡String¿ lista = new ArrayList¡String¿();

for (int i = 0; i ¡ 3; i++) lista.add( + i); return lista;

public List¡SelectItem¿ getListaStatus() List¡SelectItem¿ listaSelectItem

= new ArrayList¡SelectItem¿(); for (int i = 0; i ¡ this.listaStatusString().size(); i++)

listaSelectItem.add(new SelectItem(listaStatusString().get(i)));

return listaSelectItem;

public List¡Votante¿ getListaVotantes() VotanteDAO dao = new VotanteDAO();

List¡Votante¿ lista = dao.getTodosVotantes(); return lista;

public String getNome() return nome;

public void setNome(String nome) this.nome = nome;

public Date getDataNascimento() return dataNascimento;

public void setDataNascimento(Date dataNascimento) this.dataNascimento

= dataNascimento;

public String getIdentificacao() return identificacao;

public void setIdentificacao(String identificacao) this.identificacao = iden-

tificacao;

public TipoIdentificacao getTipoIdentificacao() return tipoIdentificacao;

public void setTipoIdentificacao(TipoIdentificacao tipoIdentificacao) this.tipoIdentificacao

= tipoIdentificacao;

public StatusVotante getStatus() return status;

public void setStatus(StatusVotante status) this.status = status;

62

public String getSenha() return senha;

public void setSenha(String senha) this.senha = senha;

public String getValorPin() return valorPin;

public void setValorPin(String valorPin) this.valorPin = valorPin;

public void setTipoIdentSelecionada(String tipoIdentSelecionada) this.tipoIdentSelecionada

= tipoIdentSelecionada;

public String getTipoIdentSelecionada() return tipoIdentSelecionada;

public void setStatusSelecionado(String statusSelecionado) this.statusSelecionado

= statusSelecionado;

public String getStatusSelecionado() return statusSelecionado;

public void setLogin(String login) this.login = login;

public String getLogin() return login;

public void setVotanteEleicaoDTO(VotanteEleicaoDTO votanteEleicaoDTO)

this.votanteEleicaoDTO = votanteEleicaoDTO;

public VotanteEleicaoDTO getVotanteEleicaoDTO() return votanteEle-

icaoDTO;

package br.com.war;

public class VotacaoDisputaBean

public String votar() return ”confirmacao”;

public String paginaCadastraCandidato() return ”candidato”;

public String paginaCadastraEleicao() return ”eleicao”;

public String paginaCadastraVotante() return ”votante”;

public String paginaCadastraDisputa() return ”disputa”;

public String paginaCadastroInicio() return ”cadastroInicio”;

package br.com.war;

import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext;

public class LoginBean

private String login; private String senha;

public String getLogin() return login;

63

public void setLogin(String login) this.login = login;

public String getSenha() return senha;

public void setSenha(String senha) this.senha = senha;

public String logar() if(login.equals(”abimael”)) if(senha.equals(”123”))

return ”autorizado”; FacesContext.getCurrentInstance().addMessage(”erro”, new FacesMes-

sage(”Login nao autorizado”));

return ;

package br.com.war;

import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext;

public class Login

private boolean loginOk;

private String login;

private String senha;

public boolean isLoginOk()

return loginOk;

public String validateLogin()

if(getLogin()!=null getSenha()!=null !getLogin().equalsIgnoreCase(getSenha()))

setLoginOk(true);

return ”secpage”;

else return ”login”;

public String logar () if(login.equalsIgnoreCase(”abimael”)) if(senha.equalsIgnoreCase(”123”)

) loginOk = true; return ”logado”; loginOk = false; FacesContext.getCurrentInstance().addMessage(”erro”,

new FacesMessage(”Login nao autorizado”)); return ”erro”;

public void setLogin(String login) this.login = login;

public String getLogin() return login;

public void setSenha(String senha) this.senha = senha;

public String getSenha() return senha;

public void setLoginOk(boolean loginOk) this.loginOk = loginOk;

package br.com.war;

64

import java.util.ArrayList; import java.util.Date; import java.util.List;

import javax.faces.model.SelectItem;

import br.com.beam.Candidato; import br.com.beam.Eleicao; import br.com.beam.StatusEleicao;

import br.com.beam.TipoAutenticacao; import br.com.beam.Votante; import br.com.dao.EleicaoDAO;

import br.com.dao.VotanteDAO;

public class EleicaoBB private String nome; private Date dataInicio; pri-

vate Date dataFim; private TipoAutenticacao tipoAutenticacao; private StatusEleicao

Status; private EleicaoDAO eleicaoDAO; private Eleicao eleicao; private String tipoAutEscol-

hido; private String statusEscolhido; private List¡Eleicao¿ listaEleicoes; private Long

idEleicao;

public EleicaoBB() eleicaoDAO = new EleicaoDAO(); eleicao = new Ele-

icao();

public String cadastrarEleicao() Eleicao eleicaoBanco = eleicaoDAO.getEleicaoPorNome(this.getNome());

String retorno = ; if (eleicaoBanco == null) eleicao.setNome(this.getNome()); ele-

icao.setDataInicio(this.getDataInicio()); eleicao.setDataFim(this.getDataFim()); this.selecionaTipoAutenticacao();

this.selecionaStatus(); eleicaoDAO.cadastrarEleicao(eleicao); retorno = ”eleicaoCadastrada”;

else retorno = ”erroNomeEleicao”; eleicao.setNome(this.getNome()); eleicao.setDataInicio(this.getDataInicio());

eleicao.setDataFim(this.getDataFim());

this.selecionaTipoAutenticacao(); this.selecionaStatus(); eleicaoDAO.cadastrarEleicao(eleicao);

String retorno = ”eleicaoCadastrada”;

return retorno;

public void selecionaStatus() if (statusEscolhido.equalsIgnoreCase(”0”))

eleicao.setStatus(StatusEleicao.NAO INICIADA); else if (statusEscolhido.equalsIgnoreCase(”1”))

eleicao.setStatus(StatusEleicao.VOTACAO);

else if (statusEscolhido.equalsIgnoreCase(”2”)) eleicao.setStatus(StatusEleicao.APURACAO DIVULGACAO DE RESULTADOS);

else eleicao.setStatus(StatusEleicao.FINALIZADA);

public void selecionaTipoAutenticacao() if (tipoAutEscolhido.equalsIgnoreCase(”0”))LOGIN SENHA);

else if (tipoAutEscolhido.equalsIgnoreCase(”1”)) eleicao.setTipoAutenticacao(TipoAutenticacao.CERTIFICADO DIGITAL);

else eleicao.setTipoAutenticacao(TipoAutenticacao.AMBOS);

65

public List¡String¿ listaTipoAutenticao() List¡String¿ listaTipoAutent =

new ArrayList¡String¿(); for (int i = 0; i ¡ 3; i++) listaTipoAutent.add( + i); return

listaTipoAutent;

public List¡SelectItem¿ getListaTipoAutenticacao() List¡SelectItem¿ lis-

taSelectItem = new ArrayList¡SelectItem¿(); for (int i = 0; i ¡ this.listaTipoAutenticao().size();

i++) listaSelectItem.add(new SelectItem(listaTipoAutenticao().get(i)));

return listaSelectItem;

public List¡String¿ listaStatusString() List¡String¿ lista = new ArrayList¡String¿();

for (int i = 0; i ¡ 4; i++) lista.add( + i); return lista;

public List¡SelectItem¿ getListaStatus() List¡SelectItem¿ listaSelectItem

= new ArrayList¡SelectItem¿(); for (int i = 0; i ¡ this.listaStatusString().size(); i++)

listaSelectItem.add(new SelectItem(listaStatusString().get(i)));

return listaSelectItem;

public List¡SelectItem¿ getListaEleicoesSelectItem() List¡SelectItem¿ lis-

taSelectItem = new ArrayList¡SelectItem¿(); listaEleicoes = eleicaoDAO.getTodasEleicoes();

for (int i = 0; i ¡ listaEleicoes.size(); i++) listaSelectItem.add(new SelectItem(listaEleicoes.get(i).getNome()));

return listaSelectItem;

public List¡Eleicao¿ getListaEleicoesComStatus() EleicaoDAO dao = new

EleicaoDAO(); return dao.getTodasEleicoes();

public List¡SelectItem¿ getListaEleicoesNaoApuradasSelectItem() List¡SelectItem¿

listaSelectItem = new ArrayList¡SelectItem¿(); StatusEleicao status = StatusEleicao.VOTACAO;

listaEleicoes = eleicaoDAO.getEleicaoPorStatus(status); for (int i = 0; i ¡ listaEle-

icoes.size(); i++) listaSelectItem.add(new SelectItem(listaEleicoes.get(i).getNome()));

return listaSelectItem;

public List¡Eleicao¿ getListaEleicoesPorStatus() EleicaoDAO dao = new

EleicaoDAO(); StatusEleicao status = StatusEleicao.VOTACAO; return dao.getEleicaoPorStatus(status);

public String getNome() return nome;

public void setNome(String nome) this.nome = nome;

66

public Date getDataInicio() return dataInicio;

public void setDataInicio(Date dataInicio) this.dataInicio = dataInicio;

public Date getDataFim() return dataFim;

public void setDataFim(Date dataFim) this.dataFim = dataFim;

public TipoAutenticacao getTipoAutenticacao() return tipoAutenticacao;

public void setTipoAutenticacao(TipoAutenticacao tipoAutenticacao) this.tipoAutenticacao

= tipoAutenticacao;

public StatusEleicao getStatus() return Status;

public void setStatus(StatusEleicao status) Status = status;

public void setTipoAutEscolhido(String tipoAutEscolhido) this.tipoAutEscolhido

= tipoAutEscolhido;

public String getTipoAutEscolhido() return tipoAutEscolhido;

public void setStatusEscolhido(String statusEscolhido) this.statusEscolhido

= statusEscolhido;

public String getStatusEscolhido() return statusEscolhido;

public void setListaEleicoes(List¡Eleicao¿ listaEleicoes) this.listaEleicoes

= listaEleicoes;

public List¡Eleicao¿ getListaEleicoes() return listaEleicoes;

public void setIdEleicao(Long idEleicao) this.idEleicao = idEleicao;

public Long getIdEleicao() return idEleicao;

package br.com.war;

import java.util.ArrayList; import java.util.List;

import javax.faces.model.SelectItem;

import br.com.beam.Disputa; import br.com.beam.Eleicao; import br.com.beam.Votante;

import br.com.dao.DisputaDAO; import br.com.dao.EleicaoDAO; import br.com.dao.VotanteDAO;

public class DisputaBB

private String nome; private String descricao; private DisputaDAO dis-

putaDAO; private Disputa disputa; private EleicaoDAO eleicaoDAO; private String

eleicaoSelecionada;

67

public DisputaBB() disputaDAO = new DisputaDAO(); disputa = new Dis-

puta(); eleicaoDAO = new EleicaoDAO(); this.getListaEleicaoSelectItem();

public String cadastrarDisputa() disputa.setNome(this.getNome()); disputa.setDescricao(this.descricao);

disputa.setEleicao(eleicaoDAO.getEleicaoPorNome(this.eleicaoSelecionada)); disputaDAO.cadastraDisputa(disputa);

return ”disputaCadastrada”;

/*public Eleicao retornaEleicaoSelecionada() eleicaoDAO = new Eleicao-

DAO(); return eleicaoDAO.getEleicaoPorStatus(status); */

public List¡Disputa¿ getListaDisputas() DisputaDAO dao = new DisputaDAO();

List¡Disputa¿ lista = dao.getTodasDisputas(); return lista;

public List¡SelectItem¿ getListaEleicaoSelectItem() List¡SelectItem¿ lis-

taSelectItem = new ArrayList¡SelectItem¿(); List¡Eleicao¿ listaEleicoes = eleicaoDAO.getTodasEleicoes();

for (int i=0;i¡listaEleicoes.size();i++) listaSelectItem.add(new SelectItem(listaEleicoes.get(i).getNome()));

return listaSelectItem;

public String getNome() return nome;

public void setNome(String nome) this.nome = nome;

public void setDescricao(String descricao) this.descricao = descricao;

public String getDescricao() return descricao;

public void setEleicaoSelecionada(String eleicaoSelecionada) this.eleicaoSelecionada

= eleicaoSelecionada;

public String getEleicaoSelecionada() return eleicaoSelecionada;

package util.xml;

import java.beans.XMLEncoder; import java.io.BufferedInputStream; im-

port java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream;

import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader;

import java.io.IOException; import java.io.OutputStream; import java.util.List; import

java.security.Key;

import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.Dom4JDriver;

public class GerenciadorXML

public String criaXML(List objetos) XStream xstream = new XStream();

68

return xstream.toXML(objetos);

public String criaXML(Key objetos) XStream xstream = new XStream();

return xstream.toXML(objetos);

public void salvaXML(String caminho, String arquivo) OutputStream out-

putStream = null; try outputStream = new FileOutputStream(caminho); catch (FileNot-

FoundException e) e.printStackTrace(); BufferedOutputStream bufferedOutputStream

= new BufferedOutputStream(outputStream); try bufferedOutputStream.write(arquivo.getBytes());

catch (IOException e1) // TODO Auto-generated catch block e1.printStackTrace();

//XMLEncoder encoder = new XMLEncoder(bufferedOutputStream); //encoder.writeObject(arquivo);

// encoder.close(); try bufferedOutputStream.close(); catch (IOException

e) e.printStackTrace(); try outputStream.close(); catch (IOException e) e.printStackTrace();

public List abreXML2 (String arquivo) XStream xstream = new XStream();

List amigos = (List) xstream.fromXML(arquivo); return amigos;

public Object abreXML (String arquivo) XStream xstream = new XStream();

return xstream.fromXML(arquivo);

public String abreXML caminho(String caminho) FileInputStream input-

Stream = null; try inputStream = new FileInputStream(caminho);

BufferedInputStream arquivo = new BufferedInputStream( new FileInput-

Stream(new File(caminho)));

byte dados[] = new byte[2048]; arquivo.read(dados, 0, 2048); return new

String(dados); catch (FileNotFoundException ex) return null; catch (IOException e)

e.printStackTrace(); return null;

public boolean deserialize(String path, Object obj) XStream stream = new

XStream(new Dom4JDriver()); FileInputStream fis = null; try File file = new File(path);

if (file.isDirectory()) throw new IllegalArgumentException (”The path must point to

a file.”); if (file.exists()) fis = new FileInputStream(path); stream.fromXML(fis, obj);

return true; return false; catch (Throwable e) return false; finally try if (fis != null)

fis.close(); catch (IOException e)

69

public Object createClient(String pathFile ) throws Exception XStream

xstream = new XStream(); FileReader reader = new FileReader(new File(pathFile));

Object obj =xstream.fromXML(reader); return obj;

¡?xml version=’1.0’ encoding=’utf-8’?¿ ¡!DOCTYPE hibernate-configuration

PUBLIC -//Hibernate/Hibernate Configuration DTD 3.0//ENhttp://hibernate.sourceforge.net/hibernate-

configuration-3.0.dtd�

¡hibernate-configuration¿

¡session-factory¿

¡!– Database connection settings –¿ ¡property name=”connection.driver class�org.postgresql.Driver¡/property¿

¡property name=”connection.url�jdbc:postgresql:postgres¡/property¿ ¡property name=”connection.username�post-

gres¡/property¿ ¡property name=”connection.password�postgresql¡/property¿

¡!– JDBC connection pool (use the built-in) –¿ ¡property name=”connection.pool size�2¡/prop-

erty¿

¡!– SQL dialect –¿ ¡property name=”dialect�org.hibernate.dialect.PostgreSQLDialect¡/property¿

¡!– Enable Hibernate’s current session context –¿ ¡property name=”current session context class�thread¡/property¿

¡!– Disable the second-level cache –¿ ¡property name=”cache.provider class�org.hibernate.cache.NoCacheProvider¡/property¿

¡!– Echo all executed SQL to stdout –¿ ¡property name=”show sql�true¡/property¿

¡!– Drop and re-create the database schema on startup ¡property name=”hbm2ddl.auto�cre-

ate¡/property¿

¡mapping resource=”org/hibernate/tutorial/domain/Event.hbm.xml”/¿ ¡map-

ping resource=”org/hibernate/tutorial/domain/Person.hbm.xml”/¿

–¿ ¡mapping class=”br.com.beam.Eleicao”/¿ ¡mapping class=”br.com.beam.Disputa”/¿

¡mapping class=”br.com.beam.Votante”/¿ ¡mapping class=”br.com.beam.Candidato”/¿

¡mapping class=”br.com.beam.PinEleicao”/¿ ¡mapping class=”br.com.beam.Login Senha”/¿

¡mapping class=”br.com.beam.Voto”/¿ ¡mapping class=”br.com.beam.VotanteEleicao”/¿

¡/session-factory¿

¡/hibernate-configuration¿

70

A.2 Cliente

package br.com.interfaces;

import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener;

import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; im-

port javax.microedition.lcdui.List;

import br.com.listas.ListaSelecaoDeEleicao;

public class FormularioAutenticandoNoSistema extends Form implements

CommandListener

Command commandProsseguir;

public FormularioAutenticandoNoSistema(String title) super(title); com-

mandProsseguir = new Command(”Prosseguir”, Command.ITEM, 1); this.addCommand(commandProsseguir);

this.setCommandListener(this);

public void commandAction(Command comandoEscolhido, Displayable

display) if (comandoEscolhido == commandProsseguir) int numero = 1; ListaSele-

caoDeEleicao listaSelecaoDeEleicao = new ListaSelecaoDeEleicao(”Selecao de Eleicao”,

List.EXCLUSIVE, new String[], null); listaSelecaoDeEleicao.insert(numero - 1, string-

Part, null);

package br.com.interfaces;

import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener;

import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; im-

port javax.microedition.lcdui.TextField;

import br.com.web.GerenciadorConexao;

public class FormularioLogin extends Form implements CommandListener

private TextField textFieldLogin, textFieldSenha; private Command com-

mandConfirmaLogin; private GerenciadorConexao gerenciadorConexao;

public FormularioLogin(String title, GerenciadorConexao gerenciadorConexao)

super(title); System.out .println(”antes de setar e o valor do gerenciadorDeConexao eh

”+ gerenciadorConexao); this.setGerenciadorConexao(gerenciadorConexao); textField-

71

Login = new TextField(”Login: ”, , 32, TextField.ANY); this.append(textFieldLogin);

textFieldSenha = new TextField(”Senha :”, , 10, TextField.PASSWORD); this.append(textFieldSenha);

commandConfirmaLogin = new Command(”Entrar”, Command.ITEM, 1); this.addCommand(commandConfirmaLogin);

this.setCommandListener(this);

public void commandAction(Command comandoEscolhido, Displayable

telaAtual) System.out.println(”entrou uahsduahsaduhsauhdisauhdi”); System.out .println(”o

valor do comandoEscolhido eh ”+ comandoEscolhido); System.out.println(”o valor do

display eh ”+ telaAtual); if (comandoEscolhido == commandConfirmaLogin) this.getGerenciadorConexao().loginNoSistema(

textFieldLogin.getString(), textFieldSenha.getString());

public void setTextFieldLogin(TextField textFieldLogin) this.textFieldLogin

= textFieldLogin;

public TextField getTextFieldLogin() return textFieldLogin;

public void setTextFieldSenha(TextField textFieldSenha) this.textFieldSenha

= textFieldSenha;

public TextField getTextFieldSenha() return textFieldSenha;

public void setCommandConfirmaLogin(Command commandConfirmaLo-

gin) this.commandConfirmaLogin = commandConfirmaLogin;

public Command getCommandConfirmaLogin() return commandConfir-

maLogin;

public void setGerenciadorConexao(GerenciadorConexao gerenciadorConexao)

this.gerenciadorConexao = gerenciadorConexao;

public GerenciadorConexao getGerenciadorConexao() return gerenciador-

Conexao;

package br.com.interfaces;

import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener;

import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; im-

port javax.microedition.lcdui.StringItem;

public class FormularioVotacaoConcluida extends Form implements Com-

mandListener

72

private StringItem stringItemVotacaoConcluida;

public FormularioVotacaoConcluida(String title) //votar(); super(title); strin-

gItemVotacaoConcluida = new StringItem(”Votacao Finalizada”, ”Obrigado!”); this.append(stringItemVotacaoConcluida);

public void commandAction(Command arg0, Displayable arg1)

package br.com.interfaces.erros;

import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener;

import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form;

public class FormularioDeErroLogin extends Form implements Comman-

dListener

private Command commandVoltaDoErroLogin;

public FormularioDeErroLogin(String title) super(title); commandVolta-

DoErroLogin = new Command(”Voltar”, Command.BACK, 1); this.addCommand(commandVoltaDoErroLogin);

this.setCommandListener(this);

public void commandAction(Command arg0, Displayable arg1) // TODO

Auto-generated method stub

package br.com.listas;

import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener;

import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Image;

import javax.microedition.lcdui.List;

public class ListaCandidatosDaDisputa extends List implements Comman-

dListener

private Command commandEscolheCandidatoEscolhidoDaLista;

public ListaCandidatosDaDisputa(String title, int listType, String[] stringEle-

ments, Image[] imageElements) super(title, listType, stringElements, imageElements);

commandEscolheCandidatoEscolhidoDaLista = new Command(”Selecionar”, Com-

mand.ITEM, 1); this.addCommand(commandEscolheCandidatoEscolhidoDaLista);

public void commandAction(Command arg0, Displayable arg1)

package br.com.listas;

73

import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection;

import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener;

import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Image;

import javax.microedition.lcdui.List;

import br.com.vectors.VetorDeDadosEleicao; import br.com.web.GerenciadorConexao;

public class ListaSelecaoDeEleicao extends List implements CommandLis-

tener

private String nomeEleicaoSelecionada; private VetorDeDadosEleicao ve-

torDeDadosEleicao;

public ListaSelecaoDeEleicao(String nome, int listType, String[] stringEle-

ments, Image[] imageElements) super(nome, listType, stringElements, imageElements);

System.out.println(”antes de deletar ”); this.deleteAll(); System.out.println(”depois

de deletar ”);

this.setTitle(nome); this.nomeEleicaoSelecionada = nome;

/*for (int i=0;i¡vetorDadosEleicao.size();i++) int cont = 0; System.out.println(”primeira

vez dentro do for—-”); String[] candidato = (String[]) vetorDadosEleicao.elementAt(i);

System.out.println(”vetorDadosCandidatos.elementAt(”+i+”) eh ”+ vetor-

DadosEleicao.elementAt(i)); */

public void buscaListaEleicoes(GerenciadorConexao gerenciadorConexao,int

votante id,String valorpin) System.gc(); gerenciadorConexao.setAcao(”lendoListaEleicoes”);

gerenciadorConexao.setUrl(”http://localhost:”+gerenciadorConexao.getNumeroPorta()+”/Servidor TCC/conexaoCelularServidor/”+

”listaEleicoes.jsf?valorpin=”+ valorpin + ”votante id=”+ votante id); gerenciadorConexao.iniciaThread();

System.gc();

private void lendoListaEleicoes(GerenciadorConexao gerenciadorConexao)

StringBuffer pesquisa = new StringBuffer(); try

String url = gerenciadorConexao.getUrl(); HttpConnection conector = (Http-

Connection) Connector.open(url); gerenciadorConexao.setConexaoHttp(conector);

if (gerenciadorConexao.getConexaoHttp().getResponseCode() == HttpCon-

nection.HTTP OK) vetorDeDadosEleicao = new VetorDeDadosEleicao();

74

String[] dados; System.out.println(”executando o preencheListaEleicoes”);

vetorDeDadosEleicao.setInputStreamDadosEleicao(gerenciadorConexao.getConexaoHttp().openInputStream());

System.out.println(”Http OK”); pesquisa = new StringBuffer(); int nu-

mero = 1, caracterLido = vetorDeDadosEleicao.getInputStreamDadosEleicao().read();

while (caracterLido != ’) dados = new String[3]; while (caracterLido != ’) // agora

encontra o nome dos candidatos pesquisa.append((char) caracterLido); caracterLido =

vetorDeDadosEleicao.getInputStreamDadosEleicao().read();

dados[0] = pesquisa.toString().trim(); pesquisa.delete(0, pesquisa.length());

// pesquisa.append((char) caractereLido); caracterLido = vetorDeDadosEleicao.getInputStreamDadosEleicao().read();

vetorDeDadosEleicao.addElement(dados); numero++; midletCelular.recebeVetorDeDadosDisputas(vetorDeDadosEleicao);

vetorDeDadosEleicao.getInputStreamDadosEleicao().close(); System.out.println(”Fechada

Conexao Preenche Lista Eleicoes”); catch (Exception e) System.out.println(”Excecao

encontrada = ”+ e);

public void commandAction(Command arg0, Displayable arg1) // TODO

Auto-generated method stub

public void setNomeEleicaoSelecionada(String nomeEleicaoSelecionada)

this.nomeEleicaoSelecionada = nomeEleicaoSelecionada;

public String getNomeEleicaoSelecionada() return nomeEleicaoSelecionada;

package br.com.midlets;

import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener;

import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Displayable;

import javax.microedition.lcdui.List; import javax.microedition.midlet.MIDlet; import

javax.microedition.midlet.MIDletStateChangeException;

import br.com.interfaces.FormularioAutenticandoNoSistema; import br.com.interfaces.FormularioLogin;

import br.com.interfaces.FormularioVotacaoConcluida; import br.com.interfaces.erros.FormularioDeErroLogin;

import br.com.listas.ListaCandidatosDaDisputa; import br.com.listas.ListaSelecaoDeEleicao;

import br.com.web.GerenciadorConexao;

public class MidletVotacaoCelular extends MIDlet implements Comman-

75

dListener

private Display display; private FormularioLogin formLogin; private For-

mularioDeErroLogin formDeErroLogin; private FormularioVotacaoConcluida formVota-

caoConcluida; private FormularioAutenticandoNoSistema formAutenticandoNoSistema;

private ListaSelecaoDeEleicao listaSelecaoDeEleicao; private ListaCandidatosDaDis-

puta listaCandidatosDaDisputa; private GerenciadorConexao gerenciadorConexao;

protected void startApp() throws MIDletStateChangeException System.out.println(”Iniciou

a aplicacao”); gerenciadorConexao = new GerenciadorConexao(this); display = Dis-

play.getDisplay(this); this.criarListas(); this.criacaoFormularios(); display.setCurrent(formLogin);

private void criacaoFormularios() formLogin = new FormularioLogin(”Tela

de Login”, gerenciadorConexao); setFormAutenticandoNoSistema(new FormularioAu-

tenticandoNoSistema(”Autenticando no Sistema”)); setFormDeErroLogin(new For-

mularioDeErroLogin(”Erro no Login”)); setFormVotacaoConcluida(new Formulari-

oVotacaoConcluida(”Votacao Concluida”));

private void criarListas() setListaSelecaoDeEleicao(new ListaSelecaoDeEle-

icao(”teste”, List.EXCLUSIVE, new String[], null)); setListaCandidatosDaDisputa(new

ListaCandidatosDaDisputa(”teste”, List.EXCLUSIVE, new String[], null));

public void commandAction(Command arg0, Displayable arg1) // TODO

Auto-generated method stub

protected void pauseApp() // TODO Auto-generated method stub

protected void destroyApp(boolean arg0) throws MIDletStateChangeEx-

ception System.out.println(”Encerrou a Aplicacao”);

public void setDisplay(Display display) this.display = display;

public Display getDisplay() return display;

public void setFormDeErroLogin(FormularioDeErroLogin formDeErroLo-

gin) this.formDeErroLogin = formDeErroLogin;

public FormularioDeErroLogin getFormDeErroLogin() return formDeEr-

roLogin;

public void setFormVotacaoConcluida(FormularioVotacaoConcluida for-

76

mVotacaoConcluida) this.formVotacaoConcluida = formVotacaoConcluida;

public FormularioVotacaoConcluida getFormVotacaoConcluida() return

formVotacaoConcluida;

public void setListaSelecaoDeEleicao(ListaSelecaoDeEleicao listaSelecaoDeEle-

icao) this.listaSelecaoDeEleicao = listaSelecaoDeEleicao;

public ListaSelecaoDeEleicao getListaSelecaoDeEleicao() return listaSe-

lecaoDeEleicao;

public void setListaCandidatosDaDisputa(ListaCandidatosDaDisputa lis-

taCandidatosDaDisputa) this.listaCandidatosDaDisputa = listaCandidatosDaDisputa;

public ListaCandidatosDaDisputa getListaCandidatosDaDisputa() return

listaCandidatosDaDisputa;

public void setFormAutenticandoNoSistema(FormularioAutenticandoNoSistema

formAutenticandoNoSistema) this.formAutenticandoNoSistema = formAutentican-

doNoSistema;

public FormularioAutenticandoNoSistema getFormAutenticandoNoSistema()

return formAutenticandoNoSistema;

public void setGerenciadorConexao(GerenciadorConexao gerenciadorConexao)

this.gerenciadorConexao = gerenciadorConexao;

public GerenciadorConexao getGerenciadorConexao() return gerenciador-

Conexao;

package br.com.vectors;

import java.io.InputStream; import java.util.Vector;

public class VetorDeDadosEleicao extends Vector

private InputStream inputStreamDadosEleicao;

public VetorDeDadosEleicao()

public void setInputStreamDadosEleicao(InputStream inputStreamDadosE-

leicao) this.inputStreamDadosEleicao = inputStreamDadosEleicao;

public InputStream getInputStreamDadosEleicao() return inputStreamDa-

dosEleicao;

77

package br.com.web;

import java.io.InputStream;

import javax.microedition.io.HttpConnection; import javax.microedition.lcdui.List;

import br.com.listas.ListaSelecaoDeEleicao; import br.com.midlets.MidletVotacaoCelular;

public class GerenciadorConexao implements Runnable

private HttpConnection conexaoHttp; private String url; private InputStream

objInputStream; private String acao = ; private String numeroPorta; private Thread

thread; private StringBuffer pesquisa = new StringBuffer(); private MidletVotacao-

Celular midletVotacaoCelular; private LoginSistema loginSistema; private ListaSele-

caoDeEleicao listaSelecaoDeEleicao;

public GerenciadorConexao(MidletVotacaoCelular midletVotacaoCelular)

this.midletVotacaoCelular = midletVotacaoCelular;

public void loginNoSistema(String login, String senha) this.setNumeroPorta(”8443”);

loginSistema = new LoginSistema(login, senha, this);

public void lerListaSelecaoDeEleicao() this.setNumeroPorta(”8443”); lis-

taSelecaoDeEleicao = new ListaSelecaoDeEleicao(”Selecao De Eleicoes”,List.EXCLUSIVE,new

String[],null); listaSelecaoDeEleicao.buscaListaEleicoes(this, 1, ”123”);

public void run() System.gc(); System.out.println(”*******************************************”);

System.out.println(”dentro do metodo RUN”); System.out.println(”*******************************************”);

System.out.println(”acao igual a ”+ acao); try if (acao.equalsIgnoreCase(”loginNoSistema”))

getLoginSistema().lendoLoginNoSistema(this); else if (acao.equalsIgnoreCase(”insereVoto”))

// inserirVoto(); else if (acao.equalsIgnoreCase(”lendoListaEleicoes”)) lendoListaEle-

icoes(this); // this.preencheListas(); // this.preencheListaDisputas();

System.gc(); catch (Exception e) System.out.println(”Excecao eh ”+ e);

public void iniciaThread() System.gc(); System.out.println(”Iniciando a

thread”); this.thread = new Thread(this); this.thread.start(); System.out.println(”Iniciou

a thread”); System.gc();

public void setConexaoHttp(HttpConnection conexaoHttp) this.conexaoHttp

= conexaoHttp;

78

public HttpConnection getConexaoHttp() return conexaoHttp;

public void setUrl(String url) this.url = url;

public String getUrl() return url;

public void setObjInputStream(InputStream objInputStream) this.objInputStream

= objInputStream;

public InputStream getObjInputStream() return objInputStream;

public void setAcao(String acao) this.acao = acao;

public String getAcao() return acao;

public void setNumeroPorta(String numeroPorta) this.numeroPorta = nu-

meroPorta;

public String getNumeroPorta() return numeroPorta;

public void setPesquisa(StringBuffer pesquisa) this.pesquisa = pesquisa;

public StringBuffer getPesquisa() return pesquisa;

public void setMidletVotacaoCelular( MidletVotacaoCelular midletVota-

caoCelular) this.midletVotacaoCelular = midletVotacaoCelular;

public MidletVotacaoCelular getMidletVotacaoCelular() return midletVota-

caoCelular;

public void setLoginSistema(LoginSistema loginSistema) this.loginSistema

= loginSistema;

public LoginSistema getLoginSistema() return loginSistema;

public void setListaSelecaoDeEleicao(ListaSelecaoDeEleicao listaSelecaoDeEle-

icao) this.listaSelecaoDeEleicao = listaSelecaoDeEleicao;

public ListaSelecaoDeEleicao getListaSelecaoDeEleicao() return listaSe-

lecaoDeEleicao;

package br.com.web;

import java.io.IOException; import java.io.InputStream;

import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection;

public class InsercaoVoto

private void inserirVoto(HttpConnection conexaoHttp, InputStream objIn-

79

putStream, String url) System.out .println(-—————————————————

————————————–”); System.out .println(-————————entrando no

insere voto——————————————”); System.out .println(-——————

———————————————————————–”); System.gc(); try conexao-

Http = (HttpConnection) Connector.open(url); if (conexaoHttp.getResponseCode() ==

HttpConnection.HTTP OK) objInputStream = conexaoHttp.openInputStream(); ob-

jInputStream.close(); System.gc(); catch (IOException e) System.out.println(”Erro

ao Inserir Voto”);

package br.com.web;

import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection;

public class LoginSistema

public LoginSistema(String login, String senha, GerenciadorConexao geren-

ciadorConexao) System.gc(); gerenciadorConexao.setAcao(”loginNoSistema”); geren-

ciadorConexao .setUrl(”http://localhost:”+ gerenciadorConexao.getNumeroPorta() +

”/Servidor TCC/conexaoCelularServidor/listaUsuario.jsf?login=”+ login + ”senha=”+

senha); gerenciadorConexao.iniciaThread(); System.gc();

public void lendoLoginNoSistema(GerenciadorConexao gerenciadorConexao)

try String url = gerenciadorConexao.getUrl(); HttpConnection conector = (HttpCon-

nection) Connector.open(url); gerenciadorConexao.setConexaoHttp(conector);

if (gerenciadorConexao.getConexaoHttp().getResponseCode() == HttpCon-

nection.HTTP OK) System.out.println(”fazendo login”); gerenciadorConexao.setObjInputStream(gerenciadorConexao

.getConexaoHttp().openInputStream()); System.out.println(”Http OK”); gerenciador-

Conexao.setPesquisa(new StringBuffer()); int caracterLido = gerenciadorConexao.getObjInputStream()

.read(); while (caracterLido != ’) gerenciadorConexao.getPesquisa() .append((char)

caracterLido); caracterLido = gerenciadorConexao.getObjInputStream() .read(); if

(gerenciadorConexao.getPesquisa().length() ¿ 9) gerenciadorConexao.getMidletVotacaoCelular().getDisplay()

.setCurrent( gerenciadorConexao .getMidletVotacaoCelular() .getFormAutenticandoNo-

Sistema()); gerenciadorConexao.setAcao(”lerListaDisputas”); gerenciadorConexao.iniciaThread();

else gerenciadorConexao.getMidletVotacaoCelular().getDisplay() .setCurrent( geren-

80

ciadorConexao .getMidletVotacaoCelular() .getFormDeErroLogin()); gerenciadorConexao.getObjInputStream().close();

System.out.println(”Fechada conexao login”); gerenciadorConexao.setAcao(”LoginJaEfetuado”);

catch (Exception e) System.out.println(”Excecao encontrada = ”+ e); System.gc();

Apendice B

Codigo Fonte Rede Misturadores

Codigo JMixNet 1

package br.edu.ufsc.labsec.util;

public class WrongConfigException extends ConfigException

public WrongConfigException(String key) super(”Property ’”+ key + ”’

was wrongly set in configuration file.”);

public class MissingConfigException extends ConfigException

public MissingConfigException(String key) super(”Property ’”+ key + ”’

was not set in configuration file.”);

package br.edu.ufsc.labsec.util;

import java.io.*; import java.util.*;

public class ConfigManager extends Properties

protected String configFileName; protected String readValue;

/** * Creates a config manager loading the specified file. */ public Config-

Manager(String fileName) throws ConfigException

FileInputStream configFile;

try configFileName = fileName; configFile = new FileInputStream(fileName);

load(configFile); configFile.close(); catch (FileNotFoundException ex) throw new

ConfigFileNotFoundException(configFileName); catch (IOException ex) throw new

1Retirado da Tese de Mestrado de Fabiano Castro Pereira[FAB 05]

82

ConfigException(”Error reading the configuration file.”);

/** * Creates a config manager loading the specified config stream. */ pub-

lic ConfigManager(InputStream configStream) throws ConfigException try load(configStream);

catch (IOException ex) throw new ConfigException(”Error reading the configura-

tion.”);

/** * Stores the configuration back to original file. */ public void store()

throws IOException FileOutputStream out = new FileOutputStream(configFileName);

store(out, ); out.close();

/** * Stores the configuration with a header back to original file. */ public

void store(String header) throws IOException FileOutputStream out = new FileOut-

putStream(configFileName); store(out, header); out.close();

/** * Get a property as an int. */ public int getInt(String key) return

Integer.parseInt(getProperty(key));

/** * Get a property as an int, returns the default value argument if the

property is not found */ public int getInt(String key, int defaultValue) readValue =

getProperty(key);

if (readValue == null) return defaultValue; else return Integer.parseInt(readValue);

/** * Get a property as a string. */ public String getString(String key)

return getProperty(key);

/** * Get a property as a string, returns the default value argument if the

property is not found */ public String getString(String key, String defaultValue) read-

Value = getProperty(key);

if (readValue == null) return defaultValue; else return readValue;

public class ConfigFileNotFoundException extends ConfigException pub-

lic ConfigFileNotFoundException(String file) super(”The configuration file ” + file +

”was not found.”);

public class ConfigException extends Exception

public ConfigException(String msg) super(msg);

83

public ConfigException(String msg, Throwable cause) super(msg, cause);

public class ReceiverServer

public static void main(String[] args) ServerSocketFactory factory = Server-

SocketFactory.getDefault(); Socket clientCon; InputStream cliInput; byte[] msgBuf =

new byte[4096]; ServerSocket server = null; int amountRead;

System.out.println(”Receiver server running.”);

try server = factory.createServerSocket(2000); catch (IOException e)

e.printStackTrace(); while (true) //start server and wait for connection try clientCon

= server.accept(); cliInput = clientCon.getInputStream();

//System.out.print(”[”); while ((amountRead = cliInput.read(msgBuf)) ¿

0) //System.out.write(msgBuf, 0, amountRead); //System.out.println(”]”); client-

Con.close(); catch (IOException e1) e1.printStackTrace();

public class ServerGUI implements ActionListener

protected static JFrame mainWindow; protected static JLabel lbConnect-

edClients; protected static JLabel lbRefusedCons; protected static JLabel lbStoredMsg;

protected static JLabel lbBadMsgs; protected static JLabel lbPerformance; protected

static JButton btService; protected static JButton btExit; protected static JMixNet-

Server server;

protected static Timer timer; protected static final int TIMER PERIOD =

1000; protected static int lastMsgCount = 0; protected static long lastPerfMeasure = 0;

protected static double elapsedTime; protected static Double performance;

public void createComponents(Container contentPane)

Font fonte = new Font(”Tahoma”, Font.PLAIN, 11); JLabel label;

contentPane.setLayout(new GridLayout(0, 2, 5, 5));

label = new JLabel(”Connected Clients:”); label.setFont(fonte); content-

Pane.add(label);

lbConnectedClients = new JLabel(”0”); lbConnectedClients.setFont(fonte);

contentPane.add(lbConnectedClients);

84

label = new JLabel(”Refused Connections:”); label.setFont(fonte); con-

tentPane.add(label);

lbRefusedCons = new JLabel(”0”); lbRefusedCons.setFont(fonte); con-

tentPane.add(lbRefusedCons);

label = new JLabel(”Stored Messages:”); label.setFont(fonte); content-

Pane.add(label);

lbStoredMsg = new JLabel(”0”); lbStoredMsg.setFont(fonte); contentPane.add(lbStoredMsg);

label = new JLabel(”Bad Messages:”); label.setFont(fonte); contentPane.add(label);

lbBadMsgs = new JLabel(”0”); lbBadMsgs.setFont(fonte); contentPane.add(lbBadMsgs);

label = new JLabel(”Performance:”); label.setFont(fonte); contentPane.add(label);

lbPerformance = new JLabel(”0 mgs/s”); lbPerformance.setFont(fonte);

contentPane.add(lbPerformance);

btService = new JButton(”Start”); btService.addActionListener(this); con-

tentPane.add(btService);

btExit = new JButton(”Exit”); btExit.addActionListener(this); contentPane.add(btExit);

timer = new Timer(TIMER PERIOD, this);

public void actionPerformed(ActionEvent e) Object src = e.getSource();

// Service ”Start”and ”Stop”button if (src == btService) if (btService.getText().equals(”Start”))

btService.setText(”Stop”); server.start(); timer.start(); else //accounting lastPerfMea-

sure = new Date().getTime(); timer.stop();

//finish btService.setText(”Start”); server.finishService(); // ”Exit”button

else if (src == btExit) System.exit(0); // Timer else if (src == timer) //measure perfor-

mance elapsedTime = (new Date().getTime() - lastPerfMeasure) / 1000.0; lastPerfMea-

sure = new Date().getTime(); performance = new Double((server.getProcessedMsgCount()

- lastMsgCount) / elapsedTime); lastMsgCount = server.getProcessedMsgCount(); lbPer-

formance.setText(performance.intValue() + ”msg/s”);

//other stats //UNDO lbBadMsgs.setText(server.getBadMsgCount() + ); lb-

StoredMsg.setText(server.getStoredMsgCount() + ); lbConnectedClients.setText(server.getConnectedClientes()

+ ); lbRefusedCons.setText(server.getRefusedConnections() + );

85

private static void createAndShowGUI() //create and set up the window

mainWindow = new JFrame(”JMixNet Server”); mainWindow.setDefaultCloseOperation(JFrame.EXIT ON CLOSE);

mainWindow.setLocation(500,300); mainWindow.setResizable(false);

ServerGUI serverGUI = new ServerGUI(); serverGUI.createComponents(mainWindow.getContentPane());

//Display the window. mainWindow.pack(); mainWindow.setVisible(true);

public static void main(String[] args) throws FileNotFoundException, JMixNe-

tException JMixNetServer server;

//create JMixNet server according to command line args if (0 == args.length)

server = new JMixNetServer(); else server = new JMixNetServer(new FileInputStream(args[0]));

//creating and showing GUI. javax.swing.SwingUtilities.invokeLater(new

Runnable() public void run() createAndShowGUI(); ); ServerGUI.setServer(server);

public static void setServer(JMixNetServer server) ServerGUI.server =

server;

public interface MessageDeliverer public void deliverMsg(ByteBuffer ms-

gBuffer);

public class MessageBatch

//buffers-related protected LinkedList emptyBuffers; protected LinkedList

fullBuffers; protected LinkedList flushBuffers; protected ByteBuffer anEmptyBuffer;

protected ByteBuffer aFullBuffer; protected int allocationCount = 0;

//configuration-related protected int msgSize; protected int poolSize; pro-

tected int flushPercent;

//flush-related protected int numChosenMsg; protected Iterator it; protected

ByteBuffer currentBuffer; protected int i;

/** * Creates the batch. * * @param batchSize Size of the batch. *

@param poolSize Size of the pool of messages to keep on each round. * @param

flushPercent Percentage of message to be sent on each round. * @param msgSize

Size of the messages contained by the batch. */ public MessageBatch(int initialBatch-

Size, int poolSize, int flushPercent, int msgSize) emptyBuffers = new LinkedList();

86

fullBuffers = new LinkedList(); ByteBuffer newMsgBuffer;

this.msgSize = msgSize; this.poolSize = poolSize; this.flushPercent = flush-

Percent;

//create message buffers for (int i = 0; i ¡ initialBatchSize; i++) newMsg-

Buffer = ByteBuffer.allocate(msgSize); if (++allocationCount emptyBuffers.add(newMsgBuffer);

/** * Returns an empty buffer. */ public ByteBuffer getEmptyBuffer()

if (emptyBuffers.size() ¿ 0) //take from emptyBuffers it = emptyBuffers.iterator();

anEmptyBuffer = (ByteBuffer)it.next(); it.remove(); else //allocate new anEmpty-

Buffer = ByteBuffer.allocate(msgSize); if (++allocationCount return anEmptyBuffer;

/** * Add the new buffer to the full buffers set. * * @param newBuffer

The buffer to be added. */ public void addFullBuffer(ByteBuffer newBuffer) full-

Buffers.add(newBuffer);

/** * Add the new buffer to the empty buffers set. * * @param newBuffer

The buffer to be added. */ public void addEmptyBuffer(ByteBuffer newBuffer) emp-

tyBuffers.add(newBuffer);

/** * Add all buffers passed in to the empty buffers set. * * @param

buffers The buffers to be added. */ public void addEmptyBuffers(Collection buffers)

emptyBuffers.addAll(buffers);

/** * Verify if there are enough messages to make a flush. */ public boolean

isReadyToFlush() //if there is at least one message over the pool size, it is ready to flush

return fullBuffers.size() - poolSize ¿= 1;

/** * Returns the selected messages to be flushed. */ public LinkedList

getFlushList() flushBuffers = new LinkedList();

//number of chosen messages to be flushed numChosenMsg = (new Dou-

ble(flushPercent * (fullBuffers.size() - poolSize) / 100.0)).intValue();

//at least one message must be flushed if (numChosenMsg == 0) numCho-

senMsg = 1;

//mix and leave just the chosen messages Collections.shuffle(fullBuffers);

87

Object obj; for (i = 0; i ¡ numChosenMsg; i++) obj = fullBuffers.removeFirst(); flush-

Buffers.add(obj); return flushBuffers;

/** * Get all full buffers. * * @return all full buffers. */ public LinkedList

getWholeList() return new LinkedList(fullBuffers);

public class JMixNetServer extends Thread

//configuration-related protected JMixNetConfigManager config;

//message handling protected int messageSize; protected MessageBatch

messageBatch; protected int sessionKeyFieldSize; protected final int sessionKeySize =

16; //AES protected final int parametersSize = 18; //AES parameters protected final int

hashFieldSize = 16; //MD5 protected byte[] receivedHash = new byte[hashFieldSize];

protected String strReceivedHash; protected byte[] plainData; protected Iterator itera-

tor; protected int flushPeriod; protected long lastFlush; protected boolean isGoodMes-

sage; protected HashMap receivedMsgTrack = new HashMap(); protected int maxMs-

gTrackSize;

//accounting protected int connectedClients = 0; protected int refusedCon-

nections; protected int badMsgCount; protected int processedMsgCount;

//flush-related protected ByteBuffer flushMessage; protected LinkedList

flushList; protected DelivererThread delivererThread;

//reports protected PrintStream errorReport = System.err; protected PrintStream

serverReport = System.out;

//cryptographers and hash protected SymCryptographer symCrypto; pro-

tected AsymCryptographer asymCrypto; protected MessageDigest digester;

//to wait for previous server protected SSLServerSocketFactory server-

SocketFactory = null; protected SSLServerSocket serverSocket = null; protected SSLSocket

previousServerSocket = null;

//to connect to the next server protected SSLSocketFactory socketFactory

= null; protected SSLSocket nextServerSocket = null;

//to receive and send messages protected InputStream previousServerInput

= null; protected OutputStream nextServerOutput = null; protected boolean service-

88

Active = true; protected Selector selector = null;

//to receive client connections protected ServerSocketChannel serverChan-

nel = null; protected SocketChannel clientSocket = null; protected HashMap client-

Buffers = new HashMap(); protected HashMap allowedClients;

/** * Construct the server with initial setup. */ public JMixNetServer()

throws JMixNetException try config = new JMixNetConfigManager(); catch (Con-

figException ex) showError(”Config error occurred:”+ ex.getMessage()); throw new

JMixNetException(ex); configureServer();

/** * Construct the server with initial setup, based on specified config file.

* * @param configFile Configuration file other than ”jmixnet.cfg”*/ public JMixNet-

Server(InputStream configStream) throws JMixNetException try config = new JMixNet-

ConfigManager(configStream); catch (ConfigException ex) showError(”Config error

occurred:”+ ex.getMessage()); throw new JMixNetException(ex); configureServer();

/** * Configurations based on config file. */ protected void configure-

Server() throws JMixNetException //ensure Bouncy Castle Provider is available if (Se-

curity.getProvider(”BC”) == null) Security.addProvider(new BouncyCastleProvider());

//SSL-related settings System.setProperty(”javax.net.ssl.keyStore”, config.getKeyStoreLocation());

System.setProperty(”javax.net.ssl.keyStorePassword”, config.getKeyStorePassword());

//message batch config messageSize = config.getMessageSize(); message-

Batch = new MessageBatch(config.getMessageBatchSize(), config.getPoolSize(), con-

fig.getFlushPercent(), messageSize); flushPeriod = config.getFlushPeriod(); plainData

= new byte[messageSize]; maxMsgTrackSize = config.getMaxMsgTrackSize();

//define allowed clients allowedClients = config.getAllowedClients();

//cryptography services and hash try symCrypto = new SymCryptogra-

pher(); asymCrypto = new AsymCryptographer(config.getKeyStoreLocation(), con-

fig.getKeyStorePassword()); asymCrypto.useAlias(”serverKey”, null); sessionKeyField-

Size = X509CertificateInfo.getKeyBytesSize((X509Certificate)asymCrypto.getCertificate());

digester = MessageDigest.getInstance(”MD5”); catch (CryptoException ex) showEr-

ror(”Unable to use cryptography services:”+ ex.getMessage()); throw new JMixNe-

89

tException(ex); catch (NoSuchAlgorithmException ex) showError(”Unable to get a

message digest instance:”+ ex.getMessage()); throw new JMixNetException(ex);

/** * Uses error report to display desired error message. * * @param

message Error message to be shown. */ protected void showError(String message)

errorReport.println(”ERROR: ”+ message);

/** * Uses server report to display desired log message. * * @param mes-

sage Log message to be shown. */ protected void showLog(String message) server-

Report.println(”Log: ”+ message);

/** * Set the PrintStream object to be used as the error report. * * @param

report PrintStream object to be used as the error report. */ public void setErrorRe-

port(PrintStream report) errorReport = report;

/** * Set the PrintStream object to be used as the server report. * * @param

report PrintStream object to be used as the server report. */ public void setServerRe-

port(PrintStream report) serverReport = report;

/** * Based on the mixnet chain configuration, connects to the next mix. */

protected void connectToNextServer() throws JMixNetException showLog(”Connecting

to next server on port ”+ String.valueOf(config.getNextServerPort()) + ”...”); try //sta-

blish connection nextServerSocket = (SSLSocket)socketFactory.createSocket(config.getNextServer(),

config.getNextServerPort()); nextServerOutput = nextServerSocket.getOutputStream();

showLog(”Connected to next server.”);

//starts deliverer thread delivererThread = new DelivererThread(); deliv-

ererThread.setServerOutput(nextServerOutput); delivererThread.start(); catch (Un-

knownHostException ex) showError(”Unable to connect to the next server. The host

” + config.getNextServer() + ”ıs unknown.”); throw new JMixNetException(ex); catch

(ConnectException ex) showError(”The next server is not available:”+ ex.getMessage());

throw new JMixNetException(ex); catch (IOException ex) showError(”An IO error

occurred when trying to connect to the next server:”+ ex.getMessage()); throw new

JMixNetException(ex);

/** * Based on the mixnet chain configuration, waits for the connection of

90

the previous mix. */ protected void waitPreviousServer() throws JMixNetException

try boolean connected = false; while (!connected) showLog(”Waiting on port ”+ con-

fig.getPort() + ”for previous server connection...”); previousServerSocket = (SSLSocket)serverSocket.accept();

//verify if the connected peer is the desired one // UNDO if (previousServer-

Socket.getSession().getPeerHost().equals(config.getPreviousServer())) connected = true;

showLog(”Previous server connected.”); previousServerInput = previousServerSocket.getInputStream();

/* else showLog(”Refused connection from ’”+ previousServerSocket.getSession().getPeerHost()

+ ”’.”); previousServerSocket.close(); */ catch (IOException ex) showError(”Error

waiting for previous server connection:”+ ex.getMessage()); throw new JMixNetEx-

ception(ex);

/** * Get the messages ready to be delivered and pass them to the deliv-

ererThread thread. * * @param msgList The messages to be delivered. */ protected

void deliverMessages(LinkedList msgList) //set new messages to be delivered and get

the handled buffers msgList = delivererThread.exchangeBuffers(msgList); message-

Batch.addEmptyBuffers(msgList);

//free msgList.clear(); msgList = null;

/** * Verifies if a new client message is repeated, discarding it (if true), *

or adding this to the message batch (if false). * This is used only by the first server.

* * @param newMsg Message just received. */ protected void handleClientMes-

sage(ByteBuffer newMsg) isGoodMessage = true; try //take the session key and ci-

pher parameters (uses plainData as temporary buffer) asymCrypto.decrypt(newMsg.array(),

0, sessionKeyFieldSize, plainData); symCrypto.setEncodedKey(plainData, 0, session-

KeySize); symCrypto.setEncodedParameters(plainData, sessionKeySize, parameters-

Size);

//decrypt data symCrypto.decrypt(newMsg.array(), sessionKeyFieldSize,

messageSize - sessionKeyFieldSize, plainData);

//compute and compare hashes digester.update(plainData, hashFieldSize,

messageSize - sessionKeyFieldSize - hashFieldSize); System.arraycopy(plainData, 0,

receivedHash, 0, hashFieldSize); isGoodMessage = MessageDigest.isEqual(digester.digest(),

91

receivedHash);

//verify message repeat strReceivedHash = new String(receivedHash); if

(receivedMsgTrack.containsKey(strReceivedHash)) showLog(”Repeated message re-

ceived.”); badMsgCount++; isGoodMessage = false; else if (receivedMsgTrack.size()

¿ maxMsgTrackSize) receivedMsgTrack.clear(); receivedMsgTrack.put(strReceivedHash,

null); catch (Exception ex) showError(”Error handling client message.”+ ex.getMessage());

isGoodMessage = false; newMsg.clear(); if (isGoodMessage) //leave the message

ready to be sent to the next server newMsg.put(plainData, hashFieldSize, plainData.length

- hashFieldSize).clear(); messageBatch.addFullBuffer(newMsg); processedMsgCount++;

//verify flush condition if (messageBatch.isReadyToFlush() ((new Date()).getTime()

- lastFlush ¿ flushPeriod)) deliverMessages(messageBatch.getFlushList()); lastFlush

= (new Date()).getTime(); else //treat the bad message as an empty buffer mes-

sageBatch.addEmptyBuffer(newMsg); badMsgCount++; showLog(”Bad message re-

ceived.”);

/** * Decrypts the message and add it to the message batch. * This is used

only by middle or last servers. * * @param newMsg Message just received. */ pro-

tected void handleServerMessage(ByteBuffer newMsg) try //take the session key and

cipher parameters (uses plainData as temporary buffer) asymCrypto.decrypt(newMsg.array(),

0, sessionKeyFieldSize, plainData); symCrypto.setEncodedKey(plainData, 0, session-

KeySize); symCrypto.setEncodedParameters(plainData, sessionKeySize, parameters-

Size);

//decrypt data and put the plain data into the plaindata array symCrypto.decrypt(newMsg.array(),

sessionKeyFieldSize, messageSize - sessionKeyFieldSize, plainData);

//leave the message ready to be sent newMsg.clear(); newMsg.put(plainData).clear();

messageBatch.addFullBuffer(newMsg);

//verify flush condition if (messageBatch.isReadyToFlush() ((new Date()).getTime()

- lastFlush ¿ flushPeriod)) //flush deliverMessages(messageBatch.getFlushList()); last-

Flush = (new Date()).getTime(); processedMsgCount++; catch (Exception ex) mes-

sageBatch.addEmptyBuffer(newMsg); badMsgCount++; //UNDO showError(”Error

92

handling server message.”+ ex.getMessage());

/* (non-Javadoc) * @see java.lang.Runnablerun() */ public void run() Byte-

Buffer msgBuffer;

showLog(”Server started.”); try //connect to next server if this is not the

last if (config.getNextServer() != null) socketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();

connectToNextServer(); //verify if this is the last, or a middle server if (config.getPreviousServer()

!= null)

//open port and wait for previous server serverSocketFactory = (SSLServer-

SocketFactory)SSLServerSocketFactory.getDefault(); try serverSocket = (SSLServer-

Socket)serverSocketFactory.createServerSocket(config.getPort()); catch (IOException

ex) showError(”Unable to create server socket:”+ ex.getMessage()); throw new JMixNe-

tException(ex); waitPreviousServer();

//verify server position if (config.getNextServer() == null) //create deliver-

erThread thread delivererThread = new DelivererThread(config.getMsgDelivererClass());

delivererThread.start(); showLog(”MixNet service active as the LAST node.”); else

showLog(”MixNet service active as a MIDDLE node.”);

boolean messageReceived; int amountRead; int totalRead;

//wait for messages from previous server while service is active while (ser-

viceActive) messageReceived = false; totalRead = 0; msgBuffer = messageBatch.getEmptyBuffer();

//wait whole message while (!messageReceived) try amountRead = pre-

viousServerInput.read(msgBuffer.array(), totalRead, messageSize - totalRead); catch

(IOException ex) //verify if this was a connection reset or an error if (ex.getMessage().equals(”Connection

reset”)) showLog(”Previous server disconnected.”); else showError(”Error reading

from previous server socket:”+ ex.getMessage());

//clear buffer msgBuffer.clear(); messageBatch.addEmptyBuffer(msgBuffer);

waitPreviousServer(); break; totalRead += amountRead; messageReceived

= totalRead == messageSize; //handle message if (messageReceived) handleServer-

Message(msgBuffer); try serverSocket.close(); catch (IOException ex) showEr-

ror(”Unable to close server socket:”+ ex.getMessage()); //wait for client connections,

93

as we are the first server else SocketChannel channel = null; SelectionKey key = null;

Iterator it = null;

//open a non-blocking service try serverChannel = ServerSocketChan-

nel.open(); serverChannel.socket().bind(new InetSocketAddress(config.getPort())); server-

Channel.configureBlocking (false); selector = Selector.open(); catch (IOException ex)

if (null == serverChannel) showError(”Unable to open server channel:”+ ex.getMessage());

else if (!serverChannel.socket().isBound()) showError(”Unable to listen for clients.

Por already in use: ”+ String.valueOf(config.getPort())); throw new JMixNetExcep-

tion(ex); int amountRead;

//accept new connections thru selector serverChannel.register(selector, Se-

lectionKey.OP ACCEPT);

//keep waiting while the service is active showLog(”MixNet service ac-

tive as the FIRST node.”); while (serviceActive) //if we have nothing to do, back and

test if service is still active try if (selector.select() == 0) continue; catch (IOEx-

ception ex) showError(”Unable to select channels:”+ ex.getMessage()); it = selec-

tor.selectedKeys().iterator();

//handle each key while (it.hasNext()) key = (SelectionKey) it.next();

//verify if this is a new connection if (key.isAcceptable()) try channel =

serverChannel.accept(); catch (IOException ex) showError(”Unable to accept client

connection:”+ ex.getMessage()); //verify if connection is still active if (channel !=

null) //allow only config file listed IPs if ((allowedClients.size() ¿ 0) !allowedClients.containsKey(channel.socket().getInetAddress().getHostAddress()))

try showLog(”Connection from ’”+ channel.socket().getInetAddress().getCanonicalHostName()

+ ”’ refused.”); refusedConnections++; channel.close(); catch (IOException ex) show-

Error(”Unable to close client channel:”+ ex.getMessage()); //allow only one active

connection per IP address else if (!clientBuffers.containsKey(channel.socket().getInetAddress()))

try //define the buffer this client will write to clientBuffers.put(channel.socket().getInetAddress(),

messageBatch.getEmptyBuffer());

//setup channel channel.configureBlocking (false); channel.register(selector,

SelectionKey.OP READ); showLog(”Client ’”+ channel.socket().getInetAddress().getCanonicalHostName()

94

+ ”’ connected.”); connectedClients++; catch (IOException ex) showError(”Unable to

set new connection channel to non-blocking:”+ ex.getMessage()); else try showLog(”Extra

client connection from ’”+ channel.socket().getInetAddress().getCanonicalHostName()

+ ”’ refused.”); refusedConnections++; channel.close(); catch (IOException ex) show-

Error(”Unable to close client channel:”+ ex.getMessage()); //verify if this is data to

be read if (key.isReadable()) channel = (SocketChannel) key.channel(); msgBuffer =

(ByteBuffer) clientBuffers.get(channel.socket().getInetAddress());

//after a whole message is received, the buffer must be taken again if (msg-

Buffer == null) msgBuffer = messageBatch.getEmptyBuffer(); clientBuffers.put(channel.socket().getInetAddress(),

msgBuffer); try if ((amountRead = channel.read(msgBuffer)) ¿ 0) //verify if the

whole message was read if (msgBuffer.position() == messageSize) //handle message

msgBuffer.flip(); handleClientMessage(msgBuffer); clientBuffers.remove(channel.socket().getInetAddress());

if (amountRead ¡ 0) //on EOF, remove client and close channel showLog(”Client

’”+ channel.socket().getInetAddress().getCanonicalHostName() + ”’ disconnected.”);

connectedClients–; clientBuffers.remove(channel.socket().getInetAddress()); channel.close();

catch (IOException ex) showError(”Unable to communicate with client:”+ ex.getMessage());

showLog(”Client ’”+ channel.socket().getInetAddress().getCanonicalHostName() + ”’

disconnected.”); connectedClients–; clientBuffers.remove(channel.socket().getInetAddress());

try channel.close(); catch (IOException e) showError(”Unable to close client chan-

nel:”+ ex.getMessage());

it.remove( ); showLog(”MixNet service finished.”);

catch (ClosedByInterruptException ex) showLog(”MixNet service fin-

ished through interruption.”); catch (ClosedChannelException ex) ex.printStackTrace();

catch (JMixNetException ex) showError(ex.getMessage());

/** * Finishes the service. */ public void finishService() //flush remaining

messages deliverMessages(messageBatch.getWholeList()); serviceActive = false;

//verify if we are the first server if (config.getPreviousServer() == null)

selector.wakeup();

this.interrupt();

95

public static void main(String[] args) throws JMixNetException, FileNot-

FoundException JMixNetServer server; BufferedReader reader = new BufferedReader(new

InputStreamReader(System.in));

//start JMixNet server according to command line args if (0 == args.length)

server = new JMixNetServer(); else server = new JMixNetServer(new FileInputStream(args[0]));

server.start();

try //wait for console command String command = reader.readLine();

while (!command.equals(”exit”)) //handle command System.out.println(”Unknown

command: [”+ command + ”]”);

//read the next command command = reader.readLine(); catch (IOExcep-

tion ex) ex.printStackTrace(); server.finishService();

System.out.println(”Main thread finished.”);

/** * @return Returns the number of bad messages received. */ public int

getBadMsgCount() return badMsgCount;

/** * @return Returns the number of connected clientes. */ public int

getConnectedClientes() return connectedClients;

/** * @return Returns the number of processed messages. */ public int

getProcessedMsgCount() return processedMsgCount;

/** * @return Returns the number of refused connections. */ public int

getRefusedConnections() return refusedConnections;

/** * @return Returns the current number of messages stored in the batch.

*/ public int getStoredMsgCount() return messageBatch.fullBuffers.size();

public class JMixNetException extends Exception

public JMixNetException() super(”Unsolvable problem encountered.”);

public JMixNetException(String message) super(message);

public JMixNetException(Throwable cause) super(cause);

public JMixNetException(String msg, Throwable cause) super(msg, cause);

public class JMixNetDeliverer implements MessageDeliverer

96

protected PrintStream errorReport = System.err; protected InetAddress re-

ceiver; protected byte[] addressBuf = new byte[4]; protected short receiverPort; pro-

tected short meaningfulMsgSize; protected Socket receiverSocket;

public void deliverMsg(ByteBuffer msgBuffer) try //get the meaningful

message size meaningfulMsgSize = msgBuffer.getShort();

//get the raw address and port msgBuffer.get(addressBuf, 0, 4); receiver =

InetAddress.getByAddress(addressBuf); receiverPort = msgBuffer.getShort();

//connect and deliver receiverSocket = new Socket(receiver, receiverPort);

receiverSocket.getOutputStream().write(msgBuffer.array(), 8, meaningfulMsgSize - 6);

receiverSocket.close(); catch (UnknownHostException ex) errorReport.println(”DELIVERY

ERROR - Unknown host: ”+ receiver.toString() + ”. Details: ”+ ex.getMessage());

catch (IOException ex) errorReport.println(”DELIVERY ERROR - Unable to com-

municate with host: ”+ receiver.toString() + ”. Details: ”+ ex.getMessage());

public class JMixNetConfigManager extends ConfigManager

protected static int DEFAULT PORT = 1981; protected static int DEFAULT MSG SIZE

= 8192; protected static int DEFAULT MSG BATCH SIZE = 100; protected static int

DEFAULT POOL SIZE = 50; protected static int DEFAULT FLUSH PERCENT =

70; protected static int DEFAULT FLUSH PERIOD = 500; protected static int DE-

FAULT MAX TRACK SIZE = 100;

protected int port; protected String address; protected int messageSize =

DEFAULT MSG SIZE; protected int messageBatchSize = DEFAULT MSG BATCH SIZE;

protected int poolSize = DEFAULT POOL SIZE; protected int flushPercent = DE-

FAULT FLUSH PERCENT; protected int flushPeriod = DEFAULT FLUSH PERIOD;

protected int maxMsgTrackSize = DEFAULT MAX TRACK SIZE; protected String

previousServer = null; protected String nextServer = null; protected int nextServerPort

= DEFAULT PORT; protected String msgDelivererClass;

public JMixNetConfigManager() throws ConfigException super(”jmixnet.cfg”);

readConfiguration();

public JMixNetConfigManager(InputStream config) throws ConfigExcep-

97

tion super(config); readConfiguration();

protected void readConfiguration() throws ConfigException String chain;

//get the port to be used, default is DEFAULT PORT port = getInt(”port”,

DEFAULT PORT);

//get the address to be used (dot-quadded or fully qualified), default is

canonical hostname try address = getProperty(”address”, InetAddress.getLocalHost().getCanonicalHostName());

catch (UnknownHostException ex) ex.printStackTrace();

//get the message size to be used, default is DEFAUL MSG SIZE message-

Size = getInt(”messageSize”, DEFAULT MSG SIZE); //get the message batch size to

be used, default is DEFAULT MSG BATCH SIZE messageBatchSize = getInt(”messageBatchSize”,

DEFAULT MSG BATCH SIZE); //get the message pool size to be used, default is

DEFAULT POOL SIZE poolSize = getInt(”poolSize”, DEFAULT POOL SIZE); //get

the flush percent to be used, default is DEFAULT FLUSH PERCENT flushPercent

= getInt(”flushPercent”, DEFAULT FLUSH PERCENT); //get the flush period to be

used, default is DEFAULT FLUSH PERIOD flushPeriod = getInt(”flushPeriod”, DE-

FAULT FLUSH PERIOD); //get the max message track size maxMsgTrackSize = getInt(”maxMsgTrackSize”,

DEFAULT MAX TRACK SIZE); //get the message deliverer class, default is JMixNet-

Deliverer msgDelivererClass = getString(”msgDelivererClass”, ”br.edu.ufsc.labsec.jmixnet.JMixNetDeliverer”);

//get the chain to define the previous and next servers chain = getProp-

erty(”chain”); if (chain == null) throw new MissingConfigException(”chain”);

//list all chain addresses String[] addresses = chain.split(”,”); String cur-

rentAddress = null; String[] addressPort = null;

//seek for local address for (int i = 0; i ¡ addresses.length; i++) //split

the address part (before the colon) and the port part (after the colon) addressPort =

addresses[i].split(”:”);

if (//local address was found? (addressPort[0].equals(address)) //config

port is not set or is the same? (addressPort.length == 1 —— (port == Integer.parseInt(addressPort[1])))

) //the previous server is the address of the previous iteration previousServer = cur-

rentAddress;

98

//verify if it is not the last if (i ¡ addresses.length - 1) //set the next server

info addressPort = addresses[i + 1].split(”:”); nextServer = addressPort[0]; if (ad-

dressPort.length ¿ 1) nextServerPort = Integer.parseInt(addressPort[1]); break; cur-

rentAddress = addressPort[0]; //verify that previous or next servers was set if ((previ-

ousServer == null) (nextServer == null)) throw new WrongConfigException(”chain”);

public String getAddress() return address;

public int getPort() return port;

public String getNextServer() return nextServer;

public int getNextServerPort() return nextServerPort;

public String getPreviousServer() return previousServer;

public int getMessageSize() return messageSize;

public int getMessageBatchSize() return messageBatchSize;

public int getPoolSize() return poolSize;

public int getFlushPercent() return flushPercent;

public int getFlushPeriod() return flushPeriod;

public String getMsgDelivererClass() return msgDelivererClass;

public String getKeyStoreLocation() return getProperty(”keyStoreLocation”,

”JMixNetServer.keystore”);

public String getKeyStorePassword() return getProperty(”keyStorePassword”,

”jmixnet”);

public Collection getServerCerts() throws ConfigException try return

X509CertificateGenerator.genCertificates( JMixNetConfigManager.class.getClassLoader().getResourceAsStream(”serverCertificates.b64”));

catch (CryptoException ex) throw new ConfigException(”Error generating certifi-

cates.”, ex);

public int getMaxMsgTrackSize() return maxMsgTrackSize;

public HashMap getAllowedClients() HashMap allowedSet = new HashMap();

String property = getProperty(”allowedClients”); if (property != null) String[] al-

lowedClients = property.split(”,”); int numAllowed = allowedClients.length; for (int

99

i = 0; i ¡ numAllowed; i++) allowedSet.put(allowedClients[i], null); return allowed-

Set;

public class JMixNetClient

//configuration-related protected JMixNetConfigManager config; protected

Iterator iterator;

//message info protected int messageSize; protected int sessionKeyField-

Size; protected int dataDescSize = 2; //a short (2 bytes) describes the size of meaning-

ful data protected final int sessionKeySize = 16; protected final int hashFieldSize = 16;

//MD5 protected byte[] encodedParameters;

//message building public int maxDataSize; protected ByteBuffer dataBuffer;

protected ByteBuffer tempBuffer; protected byte[] srcBuf; protected byte[] dstBuf;

protected int srcBufContentSize; protected int dstBufContentSize;

//reports protected PrintStream errorReport = System.err; protected PrintStream

clientReport = System.out;

//cryptographers and hash protected SymCryptographer symCrypto; pro-

tected AsymCryptographer asymCrypto; protected MessageDigest digester;

//to receive and send messages protected ArrayList serverCerts; protected

Socket connection; protected InputStream serverInput = null; protected OutputStream

serverOutput = null;

/** * Construct the client with initial setup. */ public JMixNetClient()

throws JMixNetException try config = new JMixNetConfigManager(); catch (Con-

figException ex) showError(”Config error occurred:”+ ex.getMessage()); throw new

JMixNetException(); configureClient();

/** * Construct the client with initial setup, based on specified config file.

* * @param configFile Configuration file other than ”jmixnet.cfg”*/ public JMixNet-

Client(InputStream configStream) throws JMixNetException try config = new JMixNet-

ConfigManager(configStream); catch (ConfigException ex) showError(”Config error

occurred:”+ ex.getMessage()); throw new JMixNetException(); configureClient();

/** * Configurations based on config file. */ protected void configure-

100

Client() throws JMixNetException

//ensure Bouncy Castle Provider is available if (Security.getProvider(”BC”)

== null) Security.addProvider(new BouncyCastleProvider());

//message config messageSize = config.getMessageSize(); dataBuffer =

ByteBuffer.allocate(messageSize); tempBuffer = ByteBuffer.allocate(messageSize);

try //server certificates serverCerts = (ArrayList)config.getServerCerts();

Collections.reverse(serverCerts); catch (ConfigException ex) showError(”Unable to

get server certificates:”+ ex.getMessage()); throw new JMixNetException(ex); //cal-

culate max data size the client can send iterator = serverCerts.iterator(); int totalKeyLength

= 0; while (iterator.hasNext()) totalKeyLength += X509CertificateInfo.getKeyBytesSize((X509Certificate)iterator.next());

maxDataSize = messageSize - hashFieldSize - totalKeyLength - dataDescSize;

try //cryptography services and hash symCrypto = new SymCryptogra-

pher(); asymCrypto = new AsymCryptographer(); digester = MessageDigest.getInstance(”MD5”);

catch (CryptoException ex) showError(”Unable to use cryptography services:”+ ex.getMessage());

throw new JMixNetException(); catch (NoSuchAlgorithmException ex) showEr-

ror(”Unable to get a message digest instance:”+ ex.getMessage()); throw new JMixNe-

tException();

/** * Uses error report to display desired error message. * * @param

message Error message to be shown. */ protected void showError(String message)

errorReport.println(”ERROR: ”+ message);

/** * Uses client report to display desired log message. * * @param mes-

sage Log message to be shown. */ protected void showLog(String message) clientRe-

port.println(”Log: ”+ message);

/** * Set the PrintStream object to be used as the error report. * * @param

report PrintStream object to be used as the error report. */ public void setErrorRe-

port(PrintStream report) errorReport = report;

/** * Set the PrintStream object to be used as the client report. * * @param

report PrintStream object to be used as the server report. */ public void setClientRe-

port(PrintStream report) clientReport = report;

101

/** * Connect to JMixNet server using configuration data. */ public void

connect() try connection = new Socket(config.getAddress(), config.getPort()); server-

Input = connection.getInputStream(); serverOutput = connection.getOutputStream();

catch (UnknownHostException ex) showError(”Unknown host: ”+ connection.toString()

+ ”.Details: ”+ ex.getMessage()); catch (IOException ex) showError(”Unable to com-

municate with JMixNet server.Details: ”+ ex.getMessage());

/** * Disconnect from JMixNet server. */ public void disconnect() try

connection.close(); catch (IOException ex) showError(”Unable to disconnect from

JMixNet server.Details: ”+ ex.getMessage());

/** * Send desired data to JMixNet server. * * @param data Data to be

sent. * @throws JMixNetException If data lenght is too long. */ public void send-

Data(byte[] data, int dataLength) throws JMixNetException //verify data length if

(dataLength ¿ maxDataSize) throw new DataLengthException(”Data length exceeded,

maximum allowed is ”+ maxDataSize + ”bytes.”); //put the address, port, meaningful

data size, and meaningful data tempBuffer.clear(); tempBuffer.putShort((short)dataLength);

tempBuffer.put(data, 0, dataLength);

//verify the need for padding int padding = ((dataDescSize + dataLength)

sessionKeySize - ((dataDescSize + dataLength) srcBufContentSize = dataDescSize +

dataLength + padding;

try int i; //take each certificate and build the digital envelopes for (i = 0; i

¡ serverCerts.size(); i++) //define buffers roles srcBuf = (i dstBuf = (i

//set the server certificate asymCrypto.setCertificate((Certificate)serverCerts.get(i));

sessionKeyFieldSize = X509CertificateInfo.getKeyBytesSize((X509Certificate)serverCerts.get(i));

//set symmetric key and get encoded parameters symCrypto.generateKey();

//build n-1 envelopes if (i ¡ serverCerts.size() - 1) //verify if this is the one

before the last if (i ¡ serverCerts.size() - 2) //encrypt the source symCrypto.encrypt(srcBuf,

0, srcBufContentSize, dstBuf, sessionKeyFieldSize); srcBufContentSize += session-

KeyFieldSize;

//encrypt simmetric key and cipher parameters asymCrypto.addDataToEncrypt(symCrypto.getEncodedKey(),

102

0, symCrypto.getEncodedKey().length, dstBuf, 0); encodedParameters = symCrypto.getParameters().getEncoded();

asymCrypto.encrypt(encodedParameters, 0, encodedParameters.length, dstBuf); //the

one before the last needs to take into account the hash code to the last envelope else

//encrypt the source symCrypto.encrypt(srcBuf, 0, srcBufContentSize, dstBuf, ses-

sionKeyFieldSize + hashFieldSize);

//encrypt simmetric key asymCrypto.addDataToEncrypt(symCrypto.getEncodedKey(),

0, symCrypto.getEncodedKey().length, dstBuf, 0); encodedParameters = symCrypto.getParameters().getEncoded();

asymCrypto.encrypt(encodedParameters, 0, encodedParameters.length, dstBuf, hash-

FieldSize); //build the last envelope else //calculate the hash of the source (with

padding) and add it to the begining of the source digester.update(srcBuf, hashField-

Size, messageSize - sessionKeyFieldSize - hashFieldSize); digester.digest(srcBuf, 0,

hashFieldSize);

//encrypt the source symCrypto.encrypt(srcBuf, 0, messageSize - session-

KeyFieldSize, dstBuf, sessionKeyFieldSize);

//encrypt simmetric key asymCrypto.addDataToEncrypt(symCrypto.getEncodedKey(),

0, symCrypto.getEncodedKey().length, dstBuf, 0); encodedParameters = symCrypto.getParameters().getEncoded();

asymCrypto.encrypt(encodedParameters, 0, encodedParameters.length, dstBuf); if

(encodedParameters.length != 18) System.err.println(”Parameter Length diff from 18”);

//send the message serverOutput.write(dstBuf); catch (Exception ex) throw new

JMixNetException(ex);

/** * When running the client directly, with no application tayloring, this

main method is used. * * @param args Config file name, when ”jmixnet.cfg”is not

supposed to be used. * @throws JMixNetException On unrecoverable error. */ public

static void main(String[] args) throws JMixNetException, FileNotFoundException

JMixNetClient client; ByteBuffer buffer = ByteBuffer.allocate(1024);

//to read data from console BufferedReader reader = new BufferedReader(new

InputStreamReader(System.in)); String line;

//send messages to example server (br.edu.ufsc.labsec.jmixnet.example.ReceiverServer)

InetAddress receiverAddress = null; short receiverPort = 2000; try //receiverAddress =

103

InetAddress.getLocalHost(); receiverAddress = InetAddress.getByName(”192.168.128.11”);

catch (UnknownHostException ex) ex.printStackTrace(); //start client with desired

config file if (0 == args.length) client = new JMixNetClient(); else client = new JMixNet-

Client(new FileInputStream(args[0]));

System.out.println(”Client running.”); client.connect();

//send lines read from console until ”exit”is typed /*line = reader.readLine();

while (!line.equals(”exit”)) client.sendData((line + ).getBytes()); line = reader.readLine();

*/

long lastTime = new Date().getTime(); long now; double elapsedTime; int

sentMsgs = 0; String numero; int maxDataSize = client.maxDataSize; byte[] buf = new

byte[maxDataSize]; int totalMsgs = 2000; int i = 0; //for (i = 0; i ¡ totalMsgs; i++) do

//verify exit condition try i = System.in.available(); catch (IOException ex)

//send message numero = (new Integer(i)).toString(); buffer.clear(); buffer.put(receiverAddress.getAddress());

buffer.putShort(receiverPort); buffer.put(numero.getBytes()); client.sendData(buffer.array(),

numero.getBytes().length + 6); //client.sendData(buf, maxDataSize); sentMsgs++;

//calculate throughput now = new Date().getTime(); elapsedTime = (now -

lastTime) / 1000.0; if (elapsedTime ¿ 5) lastTime = now; System.out.println(”Speed:

”+ sentMsgs / elapsedTime + ”msg/s.”); sentMsgs = 0; while (i == 0); client.disconnect();

public class DelivererThread extends Thread

//message delivery protected LinkedList newMessages; protected LinkedList

workingMessages; protected LinkedList handledMessages; protected MessageDeliv-

erer deliverer = null; protected OutputStream serverOutput; protected boolean deliv-

eryActive = true; protected Iterator it; protected ByteBuffer currentBuffer;

/** * Creates a new deliverer thread to be used by the last server. * *

@param msgDelivererClass The Class to be used to get a deliverer object. * @throws

JMixNetException If the deliverer cannot be created. */ public DelivererThread(String

msgDelivererClass) throws JMixNetException try //creates the message deliverer de-

liverer = (MessageDeliverer)(Class.forName(msgDelivererClass)).newInstance(); catch

104

(InstantiationException ex) throw new JMixNetException(”Unable to instantiate mes-

sage deliverer.Details: ”+ ex.getMessage()); catch (IllegalAccessException ex) throw

new JMixNetException(”Unable to instantiate message deliverer.Details: ”+ ex.getMessage());

catch (ClassNotFoundException ex) throw new JMixNetException(”Unable to instan-

tiate message deliverer.Details: ”+ ex.getMessage()); setupBuffers();

/** * Creates a new deliverer thread to be used by a middle server. */ public

DelivererThread() setupBuffers();

/** * Creates needed buffers. */ protected void setupBuffers() newMes-

sages = new LinkedList(); handledMessages = new LinkedList(); workingMessages =

new LinkedList();

/** * Add new messages to be handled, and return the buffers already

handled. * * @param newMsgs New messages to be delivered. * @return The buffers

already handled. */ public LinkedList exchangeBuffers(LinkedList newMsgs)

//add received new messages synchronized(newMessages) newMessages.addAll(newMsgs);

newMsgs.clear();

//return handled messages synchronized(handledMessages) newMsgs.addAll(handledMessages);

handledMessages.clear(); //tell the thread that there are new messages interrupt();

return newMsgs;

/** * Tells the thread to stop working. */ public void finishDelivery() de-

liveryActive = false; interrupt();

/** * Sets the server output to be used to deliver messages. * * @param

serverOutput The serverOutput to set. */ public void setServerOutput(OutputStream

serverOutput) this.serverOutput = serverOutput;

public void run()

while (deliveryActive) if (newMessages.size() ¿ 0) //get the new messages

synchronized(newMessages) workingMessages.addAll(newMessages); newMessages.clear();

it = workingMessages.iterator(); while (it.hasNext()) currentBuffer = (ByteBuffer)it.next();

if (deliverer != null) deliverer.deliverMsg(currentBuffer); else try serverOutput.write(currentBuffer.array());

catch (IOException ex) System.err.println(”Unable to deliver message to the next

105

server.”); currentBuffer.clear(); handledMessages.add(currentBuffer); workingMes-

sages.clear(); else try //wait a second to verify new messages sleep(1000); catch

(InterruptedException e) //do nothing

public class DataLengthException extends JMixNetException

public DataLengthException(String msg) super(msg);

public DataLengthException(String msg, Throwable cause) super(msg,

cause);

public class X509CertificateInfo

public static int getKeyBytesSize(X509Certificate cert) int keyLength =

cert.getPublicKey().getEncoded().length; return keyLength - (keyLength

public class X509CertificateGenerator

protected static CertificateFactory factory = null;

/** * Get the internal X509 factory, instantiating it if it’s not available

yet. * * @return The internal X509 factory. */ protected static CertificateFactory

getFactory() if (factory == null) try factory = CertificateFactory.getInstance(”X509”);

catch (CertificateException e) System.err.println(”Error creating CertificateFactory.”);

e.printStackTrace(); return factory;

/** * Generate a collection containing the certificates extracted from the

specified file. * * @param fileName The file containing the certificates. * @return

A certificate collection. * @throws CryptoException If some parse error ocurred.

*/ public static Collection genCertificates(String fileName) throws CryptoException

try return getFactory().generateCertificates(new FileInputStream(fileName)); catch

(CertificateException ex) throw new CryptoException(”Certificate parse error during

certificate generation.”, ex); catch (FileNotFoundException ex) throw new CryptoEx-

ception(”Certificates file not found.”, ex);

/** * Generate a collection containing the certificates extracted from the

specified stream. * * @param certStream The stream containing the certificates. *

@return A certificate collection. * @throws CryptoException If some parse error

ocurred. */ public static Collection genCertificates(InputStream certStream) throws

106

CryptoException try return getFactory().generateCertificates(certStream); catch (Cer-

tificateException ex) throw new CryptoException(”Certificate parse error during cer-

tificate generation.”, ex);

public class SymCryptographer

protected Cipher cipher; protected String algorithm = ”AES”; protected

String transformation = ”AES/CBC/NoPadding”;

protected KeyGenerator keyGenerator; protected SecretKey symKey; pro-

tected AlgorithmParameters parameters; protected boolean hasParameters = false;

protected static final int OP NONE = 0; protected static final int OP ENCRYPT

= 1; protected static final int OP DECRYPT = 2; protected static final int OP SIGN = 3;

protected static final int OP VERIFY = 4; protected int currentOperation = OP NONE;

/** * Constructs a new symmetric cryptographer. */ public SymCryptogra-

pher() throws CryptoException try cipher = Cipher.getInstance(transformation); key-

Generator = KeyGenerator.getInstance(algorithm); catch (NoSuchAlgorithmExcep-

tion ex) throw new CryptoException(”Error with algorithm definitions.”, ex); catch

(NoSuchPaddingException ex) throw new CryptoException(”Error with padding def-

initions.”, ex);

/** * Generates a new ramdom key. */ public void generateKey() symKey

= keyGenerator.generateKey(); currentOperation = OP NONE;

/** * Gets the key material of the symmetric key. * * @return The key ma-

terial of the symmetric key. */ public byte[] getEncodedKey() return symKey.getEncoded();

/** * Sets the key material of the symmetric key. * * @param key key

material. * @param offset offset of ¡tt¿key¡/tt¿ where key material starts. * @param

len key material length. */ public void setEncodedKey(byte[] key, int offset, int len)

symKey = new SecretKeySpec(key, offset, len, algorithm); currentOperation = OP NONE;

/** * Set the cipher parameters to be used. * * @param params The en-

coded parameters. * @param offset The offset in ¡tt¿params¡/tt¿ where they start.

107

* @param len The parameters length. * @throws CryptoException If a parameter

initialization error occurred. */ public void setEncodedParameters(byte[] params, int

offset, int len) throws CryptoException try byte[] newParams = new byte[len]; Sys-

tem.arraycopy(params, offset, newParams, 0, len); parameters = AlgorithmParame-

ters.getInstance(algorithm); parameters.init(newParams); hasParameters = true; cur-

rentOperation = OP NONE; catch (IOException ex) throw new CryptoException(”Erro

with parameter initialization.”, ex); catch (NoSuchAlgorithmException ex) throw new

CryptoException(”Error with algorithm definitions.”, ex);

/** * Set the cipher parameters to be used. * * @param params The en-

coded parameters. * @throws CryptoException If a parameter initialization error oc-

curred. */ public void setEncodedParameters(byte[] params) throws CryptoException

try parameters = AlgorithmParameters.getInstance(algorithm); parameters.init(params);

hasParameters = true; currentOperation = OP NONE; catch (IOException ex) throw

new CryptoException(”Erro with parameter initialization.”, ex); catch (NoSuchAlgo-

rithmException ex) throw new CryptoException(”Error with algorithm definitions.”,

ex);

/** * Discard the cipher parameters in use. */ public void resetParameters()

hasParameters = false;

/** * Returns the parameters used with this cipher. * * @return the param-

eters used with this cipher, or null if this cipher does not use any parameters. */ public

AlgorithmParameters getParameters() return cipher.getParameters();

/** * Verify if the cipher is initialized with the desired operation. * *

@param operation Desired operation * @throws CryptoException If an invalid key

or algorithm parameter is found. */ protected void verifyOperation(int operation)

throws CryptoException try switch (operation) case OP ENCRYPT : if (currentOp-

eration != OP ENCRYPT) currentOperation = OP ENCRYPT; if (hasParameters) ci-

pher.init(Cipher.ENCRYPT MODE, symKey, parameters); else cipher.init(Cipher.ENCRYPT MODE,

symKey); break; case OP DECRYPT : if (currentOperation != OP DECRYPT) cur-

rentOperation = OP DECRYPT; if (hasParameters) cipher.init(Cipher.DECRYPT MODE,

108

symKey, parameters); else cipher.init(Cipher.DECRYPT MODE, symKey); break;

catch (InvalidKeyException ex) throw new CryptoException(”Invalid symmetric key.”,

ex); catch (InvalidAlgorithmParameterException ex) throw new CryptoException(”Invalid

algorithm parameter.”, ex);

/** * Returns the desired plain data encrypted. * * @param plainData the

data to be encrypted. * @param inputOffset * @param inputLen * @param output

* @param outputOffset * @return the encrypted data. * @throws CryptoException

if some error occurred. */ public int encrypt(byte[] plainData, int inputOffset, int

inputLen, byte[] output, int outputOffset) throws CryptoException try verifyOper-

ation(OP ENCRYPT); return cipher.doFinal(plainData, inputOffset, inputLen, output,

outputOffset); catch (BadPaddingException ex) throw new CryptoException(”Erro

with data padding.”, ex); catch (IllegalBlockSizeException ex) throw new CryptoEx-

ception(”Erro with data block size.”, ex); catch (IllegalStateException ex) throw new

CryptoException(”Wrong state found.”, ex); catch (ShortBufferException ex) throw

new CryptoException(”Buffer too small.”, ex);

/** * Returns the desired plain data encrypted. * * @param plainData the

data to be encrypted. * @return the encrypted data. * @throws CryptoException if a

padding or block size error occurred. */ public byte[] encrypt(byte[] plainData) throws

CryptoException try verifyOperation(OP ENCRYPT); return cipher.doFinal(plainData);

catch (BadPaddingException ex) throw new CryptoException(”Erro with data padding.”,

ex); catch (IllegalBlockSizeException ex) throw new CryptoException(”Erro with

data block size.”, ex);

/** * Returns the desired encrypted data decrypted. * * @param en-

cryptedData the data to be decrypted. * @return the decrypted data. * @throws Cryp-

toException if a padding or block size error occurred. */ public byte[] decrypt(byte[]

encryptedData) throws CryptoException try verifyOperation(OP DECRYPT); return

cipher.doFinal(encryptedData); catch (BadPaddingException ex) throw new Cryp-

toException(”Erro with data padding.”, ex); catch (IllegalBlockSizeException ex)

throw new CryptoException(”Erro with data block size.”, ex);

109

/** * Returns the desired encrypted data decrypted. * * @param en-

cryptedData the data to be decrypted. * @param offset the offset in ¡tt¿encryptedData¡/tt¿

where the encrypted data starts. * @param length the encrypted data length. * @re-

turn the decrypted data. * @throws CryptoException if a padding or block size error

occurred. */ public byte[] decrypt(byte[] encryptedData, int offset, int length) throws

CryptoException try verifyOperation(OP DECRYPT); return cipher.doFinal(encryptedData,

offset, length); catch (BadPaddingException ex) throw new CryptoException(”Erro

with data padding.”, ex); catch (IllegalBlockSizeException ex) throw new CryptoEx-

ception(”Erro with data block size.”, ex);

/** * Returns the desired encrypted data decrypted. * * @param en-

cryptedData the data to be decrypted. * @param offset the offset in ¡tt¿encryptedData¡/tt¿

where the encrypted data starts. * @param length the encrypted data length. * @param

output the byte buffer to write the decrypted data. * @return the amount of decrypted

data. * @throws CryptoException if a padding or block size error occurred. */ public

int decrypt(byte[] encryptedData, int offset, int length, byte[] output) throws CryptoEx-

ception try verifyOperation(OP DECRYPT); return cipher.doFinal(encryptedData,

offset, length, output); catch (BadPaddingException ex) throw new CryptoExcep-

tion(”Erro with data padding.”, ex); catch (IllegalBlockSizeException ex) throw new

CryptoException(”Erro with data block size.”, ex); catch (IllegalStateException ex)

throw new CryptoException(”Wrong state found.”, ex); catch (ShortBufferException

ex) throw new CryptoException(”Buffer too small.”, ex);

/** * @return The transformation in use. */ public String getTransforma-

tion() return transformation;

/** * @param string The transformation to be used. */ public void set-

Transformation(String string) throws NoSuchPaddingException, NoSuchAlgorithmEx-

ception transformation = string;

//initialize cipher and key generator cipher = Cipher.getInstance(transformation);

currentOperation = OP NONE; algorithm = transformation.split(”/”)[0]; keyGenerator

= KeyGenerator.getInstance(algorithm);

110

public class CryptoException extends Exception

public CryptoException(String msg) super(msg);

public CryptoException(String msg, Throwable cause) super(msg, cause);

public class AsymCryptographer

protected KeyStore keyStore; protected char[] keyStorePassword; protected

Cipher cipher; protected Key privateKey = null; protected Certificate certificate = null;

protected static final int OP NONE = 0; protected static final int OP ENCRYPT

= 1; protected static final int OP DECRYPT = 2; protected static final int OP SIGN = 3;

protected static final int OP VERIFY = 4; protected int currentOperation = OP NONE;

protected String transformation = ”RSA”;

/** * Constructs a new asymmetric cryptographer using the keystore infor-

mation provided. * * @param keyStoreFilename Name of the file containing the key-

store. * @param keyStorePassword Password to open the keystore. * * @throws Cryp-

toException if some unexpected error occurred. */ public AsymCryptographer(String

keyStoreFilename, String keyStorePass) throws CryptoException try keyStore = Key-

Store.getInstance(”JKS”); keyStorePassword = keyStorePass.toCharArray(); keyStore.load(new

FileInputStream(keyStoreFilename), keyStorePassword);

cipher = Cipher.getInstance(transformation); catch (KeyStoreException

ex) throw new CryptoException(”Error opening keystore file.”, ex); catch (IOEx-

ception ex) throw new CryptoException(”Error reading keystore file.”, ex); catch

(NoSuchAlgorithmException ex) throw new CryptoException(”Error with algorithm

definitions.”, ex); catch (CertificateException ex) throw new CryptoException(”Error

loading certificate from keystore.”, ex); catch (NoSuchPaddingException ex) throw

new CryptoException(”Error with padding definitions.”, ex);

/** * Constructs a new asymmetric cryptographer using the keystore in-

formation provided. * * @throws CryptoException if some unexpected error oc-

curred. */ public AsymCryptographer() throws CryptoException try cipher = Ci-

pher.getInstance(transformation); catch (NoSuchAlgorithmException ex) throw new

111

CryptoException(”Error with algorithm definitions.”, ex); catch (NoSuchPaddingEx-

ception ex) throw new CryptoException(”Error with padding definitions.”, ex);

/** * Tells the criptographer to use the desired alias content. * * @param

newAlias The alias to be used hereafter. * @param password The alias password.

Null to use the keystore password. * @throws CryptoException If some keystore error

occurred, or a bad password was informed. */ public void useAlias(String newAlias,

String password) throws CryptoException try //verify and use the private key con-

tained in alias if (keyStore.isKeyEntry(newAlias)) if (password == null) privateKey =

keyStore.getKey(newAlias, keyStorePassword); else privateKey = keyStore.getKey(newAlias,

password.toCharArray()); //use the certificate contained in alias certificate = key-

Store.getCertificate(newAlias); currentOperation = OP NONE; catch (KeyStoreEx-

ception ex) throw new CryptoException(”Error using alias.”, ex); catch (NoSuchAl-

gorithmException ex) throw new CryptoException(”Error using alias.”, ex); catch

(UnrecoverableKeyException ex) throw new CryptoException(”Error using alias, maybe

password is wrong.”, ex);

/** * Sets the certificate to be used. * * @param cert The certificate to be

used. */ public void setCertificate(Certificate cert) certificate = cert; currentOperation

= OP NONE;

/** * Gets the certificate in use. * * @return The certificate in use. */

public Certificate getCertificate() return certificate;

/** * Verify if the cipher is initialized with the desired operation. * *

@param operation Desired operation * @throws CryptoException If an invalid key or

algorithm parameter is found. */ protected void verifyOperation(int operation) throws

CryptoException try switch (operation) case OP ENCRYPT : if (currentOperation !=

OP ENCRYPT) currentOperation = OP ENCRYPT; cipher.init(Cipher.ENCRYPT MODE,

certificate); break; case OP DECRYPT : if (currentOperation != OP DECRYPT) cur-

rentOperation = OP DECRYPT; cipher.init(Cipher.DECRYPT MODE, privateKey);

break; catch (InvalidKeyException ex) throw new CryptoException(”Invalid sym-

metric key.”, ex);

112

/** * Returns the desired plain data encrypted using the certificate de-

fined previously. * * @param plainData the data to be encrypted. * @return the

encrypted data. * @throws CryptoException if a padding or block size error occurred.

*/ public byte[] encrypt(byte[] plainData) throws CryptoException try verifyOpera-

tion(OP ENCRYPT); return cipher.doFinal(plainData); catch (BadPaddingException

ex) throw new CryptoException(”Error with data padding.”, ex); catch (IllegalBlock-

SizeException ex) throw new CryptoException(”Error with data block size.”, ex);

/** * Returns the desired plain data encrypted using the certificate defined

previously. * * @param plainData the data to be encrypted. * @param offset the offset

in ¡tt¿plainData¡/tt¿ where the plain data starts. * @param length the plain data length.

* @param output the byte buffer to write the encrypted data. * @return the amount

of encrypted data. * @throws CryptoException if some error occurred. */ public int

encrypt(byte[] plainData, int offset, int length, byte[] output) throws CryptoException

try verifyOperation(OP ENCRYPT); return cipher.doFinal(plainData, offset, length,

output); catch (BadPaddingException ex) throw new CryptoException(”Error with

data padding.”, ex); catch (IllegalBlockSizeException ex) throw new CryptoExcep-

tion(”Error with data block size.”, ex); catch (ShortBufferException ex) throw new

CryptoException(”Buffer too small.”, ex);

/** * Returns the desired plain data encrypted using the certificate de-

fined previously. * * @param plainData the data to be encrypted. * @param off-

set the offset in ¡tt¿plainData¡/tt¿ where the plain data starts. * @param length the

plain data length. * @param output the byte buffer to write the encrypted data. *

@param outputOffset the offset in ¡tt¿output¡/tt¿ where the encrypted data starts. *

@return the amount of encrypted data. * @throws CryptoException if some error oc-

curred. */ public int encrypt(byte[] plainData, int offset, int length, byte[] output, int

outputOffset) throws CryptoException try verifyOperation(OP ENCRYPT); return

cipher.doFinal(plainData, offset, length, output, outputOffset); catch (BadPaddingEx-

ception ex) throw new CryptoException(”Error with data padding.”, ex); catch (Ille-

galBlockSizeException ex) throw new CryptoException(”Error with data block size.”,

113

ex); catch (ShortBufferException ex) throw new CryptoException(”Buffer too small.”,

ex);

/** * Returns the desired encrypted data decrypted using the private key

defined previously. * * @param encryptedData the data to be decrypted. * @return

the decrypted data. * @throws CryptoException if a padding or block size error oc-

curred. */ public byte[] decrypt(byte[] encryptedData) throws CryptoException try

verifyOperation(OP DECRYPT); return cipher.doFinal(encryptedData); catch (Bad-

PaddingException ex) throw new CryptoException(”Error with data padding.”, ex);

catch (IllegalBlockSizeException ex) throw new CryptoException(”Error with data

block size.”, ex);

/** * Returns the desired encrypted data decrypted using the private key

defined previously. * * @param encryptedData the data to be decrypted. * @param

offset the offset in ¡tt¿encryptedData¡/tt¿ where the encrypted data starts. * @param

length the encrypted data length. * @return the decrypted data. * @throws CryptoEx-

ception if a padding or block size error occurred. */ public byte[] decrypt(byte[] en-

cryptedData, int offset, int length) throws CryptoException try verifyOperation(OP DECRYPT);

return cipher.doFinal(encryptedData, offset, length); catch (BadPaddingException ex)

throw new CryptoException(”Error with data padding.”, ex); catch (IllegalBlockSize-

Exception ex) throw new CryptoException(”Error with data block size.”, ex);

/** * Returns the desired encrypted data decrypted using the private key

defined previously. * * @param encryptedData the data to be decrypted. * @param

offset the offset in ¡tt¿encryptedData¡/tt¿ where the encrypted data starts. * @param

length the encrypted data length. * @param output the byte buffer to write the de-

crypted data. * @return the amount of decrypted data. * @throws CryptoException

if a padding or block size error occurred. */ public int decrypt(byte[] encrypted-

Data, int offset, int length, byte[] output) throws CryptoException try verifyOp-

eration(OP DECRYPT); return cipher.doFinal(encryptedData, offset, length, output);

catch (IllegalArgumentException ex) throw new CryptoException(”Error with en-

crypted data.”, ex); catch (BadPaddingException ex) throw new CryptoException(”Error

114

with data padding.”, ex); catch (IllegalBlockSizeException ex) throw new CryptoEx-

ception(”Error with data block size.”, ex); catch (IllegalStateException ex) throw new

CryptoException(”Wrong state found.”, ex); catch (ShortBufferException ex) throw

new CryptoException(”Buffer too small.”, ex);

/** * Continues a multiple-part encryption or decryption operation (de-

pending on how this cipher was initialized), * processing another data part. * *

@param input the input buffer * @param inputOffset the offset in ¡tt¿input¡/tt¿ where

the input starts * @param inputLen the input length * @param output the buffer for

the result * @param outputOffset the ¡tt¿offset¡/tt¿ in output where the result is stored

* @return the number of bytes stored in ¡tt¿output¡/tt¿ * @throws CryptoException if

this cipher is in a wrong state or the given output buffer is too small to hold the result.

*/ public int addDataToEncrypt(byte[] input, int inputOffset, int inputLen, byte[] out-

put, int outputOffset) throws CryptoException try verifyOperation(OP ENCRYPT);

return cipher.update(input, inputOffset, inputLen, output, outputOffset); catch (Ille-

galStateException ex) throw new CryptoException(”Wrong state found.”, ex); catch

(ShortBufferException ex) throw new CryptoException(”Buffer too small.”, ex);

/** * @return The asymmetric transformation in use. */ public String

getTransformation() return transformation;

/** * @param string The asymmetric transformation to be used. */ public

void setTransformation(String string) throws NoSuchPaddingException, NoSuchAl-

gorithmException transformation = string; cipher = Cipher.getInstance(transformation);

currentOperation = OP NONE;

B.1 Como Executar

Como executar a rede de Misturadores JmixNet2

O primeiro passo para executar a rede de mistura e estabelecer uma ICP

(PKI) simples, na qual cada servidor deve ter um certificado assinado pela Autoridade

2Como criar/executar a rede de misturadores JmixNet esta Disponıvel em:

¡http://jmixnet.sourceforge.net/¿ Acesso em: 03 maio 2011 .

115

Certificadora da JMixNet. O nome comum ( campo CN) do certificado deve ser o

endereco IP do servidor.

Para criar a Autoridade Certificadora da JMixNet voce deve:

* Gerar a chave da Autoridade Certificadora da JMixNet (OpenSSL):

openssl req -x509 -newkey rsa:1024 -keyout jmixnet ca key.pem -out jmixnet ca.pem

* Importar o certificado da AC no arquivo ”JREHOME/lib/security/cacerts”(Java

keytool):

keytool -import -alias jmixnetCA -file jmixnet ca.cer -keystore cacerts

Para gerar os certificados de servidor (repita estes passos para cada servi-

dor) voce deve:

* Gerar o par de chaves do servidor (Java keytool):

keytool -genkey -alias serverKey -keystore JMixNetServer.keystore

* Gerar o Certificate Signing Request do servidor (Java keytool):

keytool -certreq -alias serverkey -keystore JMixNetServer.keystore -file

serverReq.csr

* Assinar o certificado do servidor (OpenSSL):

openssl x509 -in serverReq.csr -out jmixnet server66.cer -days 360 -req

-CA jmixnet ca.pem -CAkey jmixnet ca key.pem -CAcreateserial

* Importar o certificado do servidor (Java keytool):

keytool -import -alias serverKey -file jmixnet server66.cer -keystore JMixNet-

Server.keystore -trustcacerts

O proximo passo e definir o arquivo de configuracao da JMixNet (jmixnet.cfg).

Este arquivo deve conter ao menos uma propriedade, a cadeia (chain) de servidores:

Exemplo: chain=192.10.15.66,192.10.15.67,192.10.15.68,192.10.15.69

Esta configuracao indica quem e o primeiro servidor, servidores inter-

mediarios, e o ultimo servidor. A JMixNet usa a porta TCP 1981 como padrao. A

configuracao da cadeis pode conter enderecos IP ou nomes de domınio, incluindo ”lo-

calhost”.

Para executar a rede voce precisa iniciar os servidores em ordem reversa,

116

ou seja, iniciar o primeiro servidor, entao o anterior, e assim por diante. O primeiro

servidor da cadeia sera o ultimo a ser iniciado.