A presente prova de conceito (POC) é um artefato fruto do Contrato de Encomenda Tecnológica nº 001/2020, firmado entre a Secretaria de Estado da Fazenda de Santa Catarina e o Instituto Federal de Santa Catarina - IFSC.
O objetivo desta prova de conceito é restrito aos objetivos contratados entre a SEF e o IFSC, compatível apenas com a versão 3.0.0 da especificação técnica de requisitos do DAF. Este artefato não tem como objetivo implementar completamente todos os processos de negócio previstos na especificação, visto que seu intuito foi demonstrar a viabilidade de implementação, tanto do DAF quanto da integração entre o PAF, DAF e a SEF-SC, utilizando tecnologias amplamente adotadas pelo mercado de desenvolvimento de software.
Não cabe à SEF ou ao IFSC prestar suporte sobre os componentes, códigos ou excertos de código disponíveis nesta POC, sendo a presente versão considerada final, sem previsão de alterações, correção de bugs ou melhorias.
A SEF e o IFSC eximem-se de qualquer responsabilidade, direta ou indireta, por perdas ou danos, comprovadamente ou alegadamente, causados pelos artefatos disponibilizados nesta POC. Caso deseje usar os componentes e softwares aqui disponibilizados, você estará fazendo isto exclusivamente por sua conta e risco.
Sumário
- DAF-pi
- Introdução
- Instalação e configuração do DAF-pi
- Facilidades específicas do DAF-pi para ajudar no desenvolvimento do PAF
- Certificado da SEF e chave de ateste com o DAF-pi
- Limitações conhecidas
- Dependências e bibliotecas de terceiros
Na Especificação 3.0.0 do Dispositivo Autorizador Fiscal (DAF) são apresentados todos os casos de uso e protocolos que devem ser implementados pelo DAF para que o mesmo possa ser comandado pelo Programa Aplicativo Fiscal (PAF) para emissão de Nota Fiscal de Consumidor Eletrônica (NFC-e) em Santa Catarina.
Este repositório apresenta uma implementação de DAF em uma Raspberry Pi Zero W e tem como público alvo desenvolvedores de PAF, uma vez que esses precisarão ter um DAF para validar suas implementações. O DAF-pi faz parte do kit de desenvolvimento oferecido aos desenvolvedores de PAF e fabricantes de DAF. Na figura abaixo são apresentadas todas as entidades que fazem parte do kit de desenvolvimento.
- DAF-pi (este repositório)
- Implementação em Python3 de todos os casos de uso da Especificação 3.0.0 do Dispositivo Autorizador Fiscal (DAF) para ser executada exclusivamente em uma Raspberry Pi Zero W. O DAF-pi só pode ser usado como ferramenta de apoio para desenvolvimento do PAF, uma vez que a Raspberry Pi não atende os requisitos de segurança da especificação do DAF.
- O DAF-pi foi desenvolvido considerando que seria mais fácil para o desenvolvedor de PAF adquirir no mercado uma Raspberry Pi Zero W. Contudo, também foi feita uma prova de conceito de DAF, denominada DAF-poc, em um hardware com o microcontrolador MAX 32552 da Maxim. O código fonte desta prova de conceito pode ser obtido neste repositório.
- Implementação em Python3 de todos os casos de uso da Especificação 3.0.0 do Dispositivo Autorizador Fiscal (DAF) para ser executada exclusivamente em uma Raspberry Pi Zero W. O DAF-pi só pode ser usado como ferramenta de apoio para desenvolvimento do PAF, uma vez que a Raspberry Pi não atende os requisitos de segurança da especificação do DAF.
- PAF
- O PAF do kit de desenvolvimento só implementa as rotinas cruciais para interação com o DAF, SEFAZ autorizadora e SEF. Trata-se assim de uma ferramenta de apoio que poderá ser usada por desenvolvedores de PAF e fabricantes de DAF.
- SEFAZ Autorizadora
- A SEFAZ Autorizadora no kit de desenvolvimento tem como foco somente o caso de uso para autorização de uso de DF-e. A implementação consiste de uma simples rotina de persistência do DF-e autorizado para uso no banco de dados relacional usado pelo PAF. Sendo assim, não consiste de uma implementação real da SEFAZ autorizadora.
- Secretaria de Estado da Fazenda de Santa Catarina (SEF)
- A SEF no kit de desenvolvimento provê implementação para todos os casos de uso que envolvam diretamente o contribuinte e seu DAF, conforme apresentado na Especificação 3.0.0 do Dispositivo Autorizador Fiscal (DAF). Por exemplo, registro de DAF, remoção de registro, autorização para remoção de autorização retida no DAF, entre outras.
Disponibilizamos aqui uma composição Docker que permite facilmente montar um ambiente local de desenvolvimento composto pelas entidades PAF, SEFAZ autorizadora e SEF, apresentadas acima.
Nessa seção são apresentadas três abordagens para ter um DAF-pi pronto para ser usado pelo PAF:
- DAF-pi
- Introdução
- Instalação e configuração do DAF-pi
- Facilidades específicas do DAF-pi para ajudar no desenvolvimento do PAF
- Certificado da SEF e chave de ateste com o DAF-pi
- Limitações conhecidas
- Dependências e bibliotecas de terceiros
-
Requisitos de hardware
- 01 Raspberry Pi Zero W
- 01 Cabo micro-USB
- 01 Cartão micro-SD com pelo menos 8GB de armazenamento
-
Requisitos de software
- Raspberry Pi Imager para permitir instalar a imagem ISO no cartão micro-SD da Raspberry Pi Zero W
Neste link é disponibilizada uma imagem ISO do DAF-pi pronta para ser colocada no cartão micro-SD da Raspberry Pi Zero W. Essa é a maneira mais simples e rápida para ter um DAF-pi pronto para uso. Os passos para obtenção e instalação dessa imagem em um cartão micro-SD são:
- Obter a imagem do DAF-pi disponibilizada neste link
- Seguir os passos desse vídeo para instalação do sistema operacional e configuração de rede da placa
- Selecionar a imagem do DAF-pi recém obtida
- Habilitar acesso via SSH e definir uma senha de acesso para o usuário
pi
- Configurar a rede da Raspberry Pi Zero W e aguardar a finalização do processo de instalação
- Habilitar acesso via SSH e definir uma senha de acesso para o usuário
- Basta agora colocar o cartão micro SD na Raspberry Pi, conectar o cabo USB no computador onde está sendo executado o PAF e o conector micro USB na porta USB da Raspberry Pi W (é a porta micro USB mais próxima da porta HDMI).
- 👏 Pronto! Você tem um DAF-pi pronto para uso.
-
Requisitos de hardware
- 01 Raspberry Pi Zero W
- 01 Cabo micro-USB
- 01 Cartão micro-SD com pelo menos 8GB de armazenamento
-
Requisitos de software
- Raspberry Pi Imager para permitir instalar a imagem ISO no cartão micro-SD da Raspberry Pi Zero W
Nessa seção são apresentados os passos para: 1) instalar o sistema operacional Raspberry Pi OS; 2) Acessar a Raspberry Pi Zero via SSH, baixar e instalar o código fonte disponível neste repositório; 3) configurar o sistema operacional da Raspberry Pi Zero W para que a mesma atue como um DAF.
- Execute o software Raspberry Pi Imager
- Siga os passos apresentados neste video
- Habilite o acesso via SSH e defina a senha de acesso para o usuário
pi
- Configure a rede sem fio da Raspberry Pi Zero W
- Habilite o acesso via SSH e defina a senha de acesso para o usuário
- Aguarde o término do processo de escrita no cartão micro SD
- Pronto! Coloque o cartão micro SD na Raspberry PI e conecte a alimentação de energia na mesma
No passo anterior você ativou o servidor SSH na placa Raspberry e possibilitou que a mesma se conectasse na sua rede sem fio. Fazendo uso de um cliente SSH (e.g. ssh no Linux ou macOS, ou PuTTY no Windows), conecte na placa Raspberry. Para isso você poderá conectar usando o endereço IP obtido pela placa ou pelo nome raspberrypi.local
. A senha do usuário pi
foi definida por você durante a instalação do sistema operacional no cartão.
ssh pi@raspberrypi.local
cd ~
git clone https://github.com/ifsc-lased/daf-pi
cd daf-pi
python3 -m venv venv
source venv/bin/activate
pip3 install -r requirements.txt
As linhas abaixo deverão ser executadas dentro da Raspberry, por meio de uma sessão remota (i.e. SSH)
Para que a Raspberry Pi Zero W se comporte como um dispositivo USB CDC-ACM, execute uma única vez o script configura_gadget_usbcdc_daf.sh.
sudo bash res/configura_gadget_usbcdc_daf.sh
Será feito uso do supervisor para garantir que o código do DAF seja executado automaticamente sempre que a a Raspberry Pi Zero W for energizada.
cd ~/daf-pi
sudo apt-get install supervisor
sudo cp res/daf.conf /etc/supervisor/supervisord.conf
sudo supervisord -c /etc/supervisor/supervisord.conf
sudo shutdown -r now
👏 Pronto! Você tem agora uma Raspberry Pi Zero W pronta para atuar como DAF.
Entenda que com essa abordagem a comunicação serial entre DAF e PAF não será sobre a interface USB. Ou seja, não está de acordo com a especificação de requisitos do DAF e não permitirá aos desenvolvedores de PAF terem certeza que sua implementação funcionará corretamente quando estiver comandando um DAF por meio da interface USB.
Caso não tenha uma Raspberry Pi Zero W, é possível executar o DAF-pi em um computador com Linux e usar o aplicativo socat (Multipurpose relay (SOcket CAT)) para fazer o encaminhamento entre dois pseudoterminais. Essa abordagem permite que um PAF, que esteja sendo executado no mesmo computador, consiga acessar o DAF-pi.
-
Instale os pacotes Python3 e socat
sudo apt install python3 python3-venv socat
-
Execute o
socat
para criar um relay entre dois pseudoterminais (/dev/pts
). Atenção: é necessário deixar osocat
em execução.socat -d -d pty,raw,echo=0 pty,raw,echo=0
- Após executar o código acima será impresso os pseudoterminais que foram associados. No exemplo abaixo foi criado um relay entre os pseudoterminais
/dev/pts/2
e/dev/pts/3
.2022/06/03 15:24:55 socat[544737] N PTY is /dev/pts/2 2022/06/03 15:24:55 socat[544737] N PTY is /dev/pts/3 2022/06/03 15:24:55 socat[544737] N starting data transfer loop with FDs [5,5] and [7,7]
- Um dos pseudoterminais será usado pelo DAF-pi (e.g.
/dev/pts/2
) e o outro (e.g./dev/pts/3
) será usado pelo PAF.
- Após executar o código acima será impresso os pseudoterminais que foram associados. No exemplo abaixo foi criado um relay entre os pseudoterminais
-
Em um outro terminal baixe o código do DAF-pi e baixe as dependências do projeto
git clone https://github.com/ifsc-lased/daf-pi.git cd daf-pi python3 -m venv venv source venv/bin/activate pip install --upgrade pip pip install -r requirements.txt
-
Edite o arquivo
app.py
e substitua o valor/dev/ttyGS0
que está associado ao atributoport
por um dos pseudoterminais que o socat está usando. Neste exemplo será usado/dev/pts/2
. -
Execute a aplicação DAF-pi
python3 app.py
-
👏 Pronto! Você tem agora o DAF-pi sendo executado no seu computador com Linux.
- Caso queira testar este DAF, use a composição PAF SEF, mas lembre-se que é necessário definir o valor da variável
porta
no código do PAF (antes do if) para o pseudoterminal que o socat associou.- Exemplo:
porta='pts/3'
.
- Exemplo:
- Caso queira testar este DAF, use a composição PAF SEF, mas lembre-se que é necessário definir o valor da variável
Nessa seção são apresentadas comandos específicos que o DAF-pi implementa para gerar facilidades para o desenvolvimento do PAF. Todos os comandos aqui apresentados não estão de acordo com a Especificação 3.0.0 do Dispositivo Autorizador Fiscal (DAF).
O DAF-pi pode a qualquer momento ser colocado no modo padrão de fábrica
, estado no qual o dispositivo se comporta como um DAF recém adquirido. O PAF disponível no kit de desenvolvimento possui a funcionalidade para colocar o DAF-pi no modo padrão de fábrica
. Ao ser invocada, o PAF envia a mensagem com o código 9999
ao DAF-pi.
Este procedimento não reinicia a versão do
software básico
do DAF-pi, caso o mesmo tenha sido atualizado.
De acordo com a especificação do DAF, o identificador único do DAF (idDAF
) é imutável. Porém, o desenvolver de PAF poderia ter a necessidade de testar seu PAF com mais de um DAF. Para que o desenvolver não precise ter vários DAF-pi, o DAF-pi implementa um comando que permite alterar seu idDAF
.
O PAF disponível no kit de desenvolvimento possui a funcionalidade para solicitar a alteração do idDAF
do DAF-pi. Ao ser invocada, o PAF envia a mensagem com o código 9997
ao DAF-pi. Esse procedimento gera um novo idDAF
e coloca o DAF-pi no padrão de fábrica
, ou seja, o mesmo se comporta como um DAF recém adquirido.
Este procedimento não reinicia a versão do
software básico
do DAF-pi, caso o mesmo tenha sido atualizado.
De acordo com a especificação do DAF, o DAF pode ir para o estado inutilizado se acontecer alguma ação não permitida, como uma tentativa de revelação do material criptográfico mantido em sua memória segura.
O PAF disponível no kit de desenvolvimento possui a funcionalidade para colocar o DAF-pi no estado inutilizado. Ao ser invocada, o PAF envia a mensagem com o código 9998
ao DAF.
O DAF-pi, quando no estado de inutilizado, não transmitirá suas informações a cada 30 segundos, como descrito na especificação de requisitos do DAF. No caso, transmitirá essas informações (com exceção do conteúdo da partição do SB e da MT) sempre que receber uma mensagem do PAF que seja diferente da mensagem que o levaria para o modo
padrão de fábrica
.
De acordo com a Especificação Técnica de Requisitos do DAF, o DAF deverá conter o certificado digital da SEF. Por outro lado, a SEF já deverá ter a chave pública, par da chave de ateste do DAF.
A SEF deste kit de desenvolvimento contém a chave pública, par da chave de ateste do DAF-pi. E o DAF-pi contém o certificado da SEF. Esse certificado digital da SEF é auto assinado e tem validade até 2031-05-27 14:35:18
.
A especificação do DAF permite o uso de chaves criptográficas RSA ou EC. A chave de ateste do DAF-pi é uma chave EC P-384, enquanto que a chave pública contida no certificado da SEF também é uma chave EC P-384.
Desenvolvedores de DAF, que forem usar o kit de desenvolvimento disponibilizado, precisarão incluir a chave de ateste na SEF do kit e dentro de seu DAF terão que incluir o certificado da SEF.
Em função da placa Raspberry Pi Zero W não possuir um acelerador criptográfico, algumas operações podem demorar mais tempo que o valor de timeout da camada ARQ do protocolo de comunicação definido na Especificação Técnica de Requisitos do DAF.
Desta forma, na implementação do DAF-pi o valor do timeout da camada ARQ é de 2 segundos. O PAF que for interagir com este DAF-pi deve definir o mesmo valor para o timeout da camada ARQ de sua implementação do protocolo de comunicação do DAF.
O PAF disponível no kit de desenvolvimento tem o timeout definido em 2 segundos.
O código do DAF-pi foi desenvolvido na linguagem Python3 e faz uso das seguintes bibliotecas de terceiros:
Biblioteca | Função | Licença |
---|---|---|
JWCrypto | Decifragem de token JWE | GNU Lesser GPLv3 |
cryptography | Operações criptográficas | Apache 2.0 e BSD |
PyCryptodome | Operações criptográficas | BSD e OCB |
PyJWT | Geração e validação de tokens JWT | MIT License |
Authlib | Dependência da biblioteca PyJWT | BSD |
pySerial | Comunicação serial | BSD |
TinyDB | Representação dos tipos de memória do DAF | MIT License |
pytype | Documentação do código | Apache 2.0 e MIT |
wheel | Dependência de algumas bibliotecas | MIT License |