sexta-feira, 23 de junho de 2017

Certificado Inválido no Firefox

Criei um programa que adiciona certificados ao Firefox, para possibilitar fazer comunicação via websocket com sites HTTPS. Sem o certificado, os browsers não reconhecem o site porque não podem enviar uma requisição de uma conexão encriptada para uma não encriptada.

Para fazer isso, gero dois certificados:
- um deles é o root, auto-assinado;
- o segundo é de fato usado na conexão, é assinado pelo primeiro.

No caso de Chrome e IE, o certificado é adicionado na Store do Windows. Nela, adiciona-se o certificado CA na Root Store e o SSL na My. No caso do Firefox, tem uma Store própria. Para adicionar o certificado, eu estava usando isso:

certutil.exe -d [cert8.db path] -A -t "TCu,Cuw,Tuw" -n [name] -i [crt path]
-d: diretório do firefox
-A: comando de adicionar

Um dia fui rodar e descobri que não funcionava mais no Firefox. Na hora de adicionar, não reportava erro. Usando a opção -L, o certificado era listado como adicionado. Mesmo olhando em Tools > Options > Advanced > Certificates (meu Firefox está em inglês), estava lá. Mas o Firefox continuava dizendo que o site não era confiável. 

Procurei um pouco, perdido. Fui olhar a VM de Linux, lá ainda funcionava, com o mesmo código. Um tempo depois, olhei a versão do Firefox. A última atualização era recente, 13 de junho, versão 54. Falava em mudanças de segurança, mas dizia que era CSS. Corri um pouco mais atrás do meu rabo. Fui no Linux. A versão era anterior. Atualizei. Parou de funcionar também!

Quase desisti nesse momento. Até que alguém visse isso, em algo tão recente, até que incomodasse gente suficiente...

Comecei a testar fazer outras coisas. Mudei a permissão usada ("TCu,Cuw,Tuw"). Reli o erro, que falava de Issuer. Adicionei o certificado Root no Firefox também. No meio do caminho descobri uma coisa útil: o certutil tem uma opção -V, que valida parcialmente o certificado. Adicionando CA ainda não funcionava. Tentei com alguns tipos de permissão, erros diferentes aconteciam. Quase desistindo de novo.

Fui até o Firefox e tentei adicionar o certificado na mão. Deu uma mensagem de erro, ao contrário do que o certutil fazia - que simplesmente adicionava. Sobre o parcialmente: o mesmo certificado que deu como válido no -V apontou inválido no Firefox direto. Procurei a mensagem no Google. Descobri que precisava de uma flag no certificado CA, em extensions, uma basic extension com valor CA=true.

Resumo da ópera:
Adicionar certificado CA:
certutil.exe -d [cert8.db path] -A -t "TC,," -n [name] -i [crt path]

Adicionar certificado SSL:
certutil.exe -d [cert8.db path] -A -t "u,," -n [name] -i [crt path]

Em C#, usando BouncyCastle, para adicionar o CA=true:
var generator = new X509V3CertificateGenerator();
(...)
var basicContraint = new BasicConstraints(true);
generator.AddExtension(
    X509Extensions.BasicConstraints, true, basicContraint
);

Voilá! Funcionou de novo. E pude ir feliz pra casa na segunda. Ao contrário de sexta, quando descobri o final do dia que tinha feito uma co