Na firma estamos com um projeto de autenticar clientes usando OpenBAO.  OpenBAO, pro não iniciados, é um fork do Vault da Hashicorp que por sua vez é uma forma de você gerar sua própria CA, Certificate Authority, e criar seus próprios certificados.  E com isso temos um caso novo que são os computadores com TPM, Trusted Platform Module, que é um hardware que gera e armazena suas chaves criptográficas.

Na forma antiga, você recebe um token da rede e usa esse token pra pedir pro OpenBAO pra gerar tanto certificado quanto a chave privada.  Com TPM, que gera sua própria chave privada e armazena localmente, você precisa gerar uma chave privada localmente e depois armazenar criar uma CSR, Certificate Signing Request, pra solicitar que seja gerado um certificado.

É preciso instalar o pacote "tpm2-tools", que vai baixar o que é preciso pra falar com o TPM.  Também é preciso adicionar seu usuário no grupo "tss", do contrário somente como "root" vai conseguir acessar os devices do TPM.

Os comandos pra gerar a chave privada via TPM e o CSR são esses abaixo:


tpm2_createek -G ecc -c ek_ecc.ctx || echo "TPM already initialized"
tpm2_createak -C ek_ecc.ctx -G ecc -g sha256 -s ecdsa -c ak_ecc.ctx || echo "TPM already initialized"
tpm2_evictcontrol -c ak_ecc.ctx 0x81000000 || echo "TPM already initialized and it is persistent"

openssl req \
    -provider tpm2 \
    -provider default \
    -propquery '?provider=tpm2' \
    -new \
    -subj "/CN=client.loureiro.eng.br/" \
    -key handle:0x81000000 \
    -out client.csr

Depois disso é enviar ao OpenBAO, que no caso está rodando via container pra testes na porta 8200 e sem TLS habilitado.  O truque do "data" é colocar o certificado inteiro em uma linha só, por isso o "sed" e "tr".


curl \
    -s \
    -o client_data.json \
    --cacert openbao_ca.crt \
    --header "X-Vault-Token: $TOKEN" \
    --header "Content-Type: application/json" \
    --data "{\"csr\": \"$(
        cat $CLIENT_CSR | sed "s/\$/@@@/g" | tr -d "\n" | sed "s/@@@/\\\n/g"
    )\",\"common_name\": \"client\",\"alt_names\": \"client.loureiro.eng.br\",\"ttl\": \"90d\"}" \
    "http://openbao:8200/v1/pki/sign/client-loureiro"

Feito isso, os certificados ficam disponíveis no client_data.json.  Basta extrair e usar.


jq -re .data.certificate client.csr
export OPENSSL_CONF=$PWD/openssl.cnf
export OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules
curl \
    --cert client.csr \
    --cacert openbao_ca.crt \
    --key handle:0x81000000 \
    --key-type PROV \
    --engine tpm2 \
    -H "Content-Type: application/json" \
    -d '{"agent_id":"0001","message":"testing"}' \
    https://api.loureiro.eng.br/v1/getdata

Na falta de uma imagem melhor ou relacionada, deixei essa do meu peruzão que comi durante o Sweden Rock.