openbao

openbao

  • Autenticando curl com certificado usando TPM

    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.