Aceda aos metadados de segurança e valide pacotes

Este documento descreve como aceder aos metadados de segurança a partir do contentor do assuredoss-metadataCloud Storage. Para ver uma descrição dos metadados de segurança, consulte os campos de metadados de segurança.

Este documento aplica-se apenas ao nível premium do Assured OSS. Para o nível gratuito, consulte Validar assinaturas no nível gratuito do Assured OSS.

Antes de começar

Configure a autenticação.

Extraia os metadados

Pode usar os comandos gcloud ou curl para transferir os metadados. Crie o URL para ambos com as seguintes informações:

  • Idioma: java, python, golang ou javascript. O valor tem de estar em letras minúsculas.
  • Package_ID: uma das seguintes opções:

    • Java: groupId:artifactId
    • Python: packageName
    • JavaScript: um dos seguintes: @org-name/package-name, @username/package-name ou package-name
    • Ir: packageName

    O valor tem de estar em minúsculas.

  • Versão: a versão do pacote.

O URL tem de ter o seguinte formato:

gcloud

gs://assuredoss-metadata/language/package_id/version/metadata.json

O URL tem de estar em minúsculas.

Os URLs de exemplo incluem o seguinte:

  • URL de Python de exemplo: gs://assuredoss-metadata/python/blessed/1.20.0/metadata.json

  • Exemplo de URL Java: gs://assuredoss-metadata/java/org.apache.logging.log4j:log4j-core/2.17.1/metadata.json

  • URL do JavaScript de exemplo: gs://assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json

  • URL do Go de exemplo: gs://assuredoss-metadata/golang/github.com/rs/zerolog/1.9.1/metadata.json

curl

https://storage.googleapis.com/assuredoss-metadata/language/package_id/version/metadata.json

O URL tem de estar em letras minúsculas.

Os URLs de exemplo incluem o seguinte:

  • URL de Python de exemplo: https://storage.googleapis.com/assuredoss-metadata/python/blessed/1.20.0/metadata.json

  • Exemplo de URL Java: https://storage.googleapis.com/assuredoss-metadata/java/org.apache.logging.log4j:log4j-core/2.17.1/metadata.json

  • URL do JavaScript de exemplo: https://storage.googleapis.com/assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json

  • URL do Go de exemplo: https://storage.googleapis.com/assuredoss-metadata/golang/github.com/rs/zerolog/1.9.1/metadata.json

  1. Transfira os metadados:

gcloud

gcloud storage cp "gs://assuredoss-metadata/language/package_id/version/metadata.json" outputFolderLocation

curl

curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -L https://storage.googleapis.com/assuredoss-metadata/language/package_id/version/metadata.json -o metadata.json

Agora, pode validar as assinaturas. Existem duas opções:

Valide as assinaturas de pacotes transferidos através da ferramenta aoss-verifier

Use a ferramenta aoss-verifier para validar os metadados do pacote.

Antes de usar esta ferramenta, instale o Go.

  1. Instale a ferramenta aoss-verifier.

  2. Exportar $(go env GOPATH)/bin.

  3. Execute o comando aoss-verifier verify-metadata.

    aoss-verifier verify-metadata \
       --metadata_type TYPE \
       --language LANGUAGE \
       --package_id PACKAGE_ID \
       --version VERSION \
       [--disable_certificate_verification] \
       [--temp_downloads_path TEMP_DOWNLOADS_DIR_PATH] \
       [--disable_deletes]
    

    Substitua o seguinte:

    • TYPE: os valores possíveis são premiuminfo.
    • LANGUAGE: o idioma do pacote. O valor tem de estar em letras minúsculas.
    • PACKAGE_ID: para Java, o formato é groupId:artifactId. Para Python e Go, o formato é packageName. O valor tem de estar em letras minúsculas.
    • VERSION: a versão do pacote.

    --disable_certificate_verification é uma flag opcional que ignora a correspondência do certificado de entidade final com o certificado de raiz através da cadeia de certificados, se for usada.

    --temp_downloads_path é uma flag opcional para definir o caminho onde quer transferir os ficheiros (substitua TEMP_DOWNLOADS_DIR_PATH). Se a flag não estiver definida, os ficheiros são transferidos para a pasta tmp_downloads no diretório atual.

    --disable_deletes é uma flag opcional que mantém os ficheiros transferidos. Por predefinição, a ferramenta limpa todos os ficheiros transferidos.

Para mais informações, consulte o ficheiro README.

Valide manualmente as assinaturas dos pacotes transferidos

Só pode validar a assinatura do artefacto para os ficheiros binários criados de forma segura pelo Assured OSS e não para os fornecidos pelo Assured OSS através de proxies.

Para validar assinaturas manualmente, pode usar várias ferramentas. Os passos seguintes usam a CLI gcloud, o OpenSSL (versão 3.0.1 ou superior) e o jq (1.7.1 ou superior) para validar as assinaturas no Linux.

  1. Transfira o ficheiro de metadados. Conforme descrito nos campos de metadados de segurança, o ficheiro de metadados contém um campo SBOM no campo buildInfo. A SBOM contém o artefacto (por exemplo, um ficheiro JAR ou EGG) que foi criado juntamente com uma anotação que representa a assinatura. Este artefacto permite-lhe determinar o ID SPDX.

    Por exemplo, se o nome do artefacto for artifact_name, o spdx_id é SPDXRef-Package-artifact_name. Para validar um pacote com o nome gradio-3.30.0-py3-none-any.whl, o spdx_id é SPDXRef-Package-gradio-3.30.0-py3-none-any.whl.

  2. Extraia o resumo SHA-256 do ficheiro de metadados:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.digest[0].digest' | cut -d ' ' -f1 > expectedDigest.txt
    

    Substitua o seguinte:

    • METADATA_FILENAME: o nome do ficheiro de metadados de segurança.

    • SPDX_ID: o identificador SPDX.

  3. Calcule o resumo do artefacto:

    sha256sum ARTIFACT_FILE | cut -d ' ' -f1 > actualDigest.txt
    

    Substitua ARTIFACT_FILE pelo nome do ficheiro do artefacto.

  4. Verifique se existem diferenças entre os dois:

    diff actualDigest.txt expectedDigest.txt
    

    Se não existir diferença, não existe saída.

  5. Extraia o resumo do campo para um ficheiro .bin:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.digest[0].digest' | cut -d ':' -f2 | xxd -r -p > digest.bin
    
  6. Extraia a assinatura do resumo para um ficheiro .sig:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.signature[0].signature' | xxd -r -p > sig.sig
    
  7. Extraia a chave pública do certificado público para um ficheiro .pem:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.certInfo.cert' | openssl x509 -pubkey -noout  > pubKey.pem
    
  8. Valide a assinatura do resumo através da chave pública extraída:

    openssl pkeyutl -in digest.bin -inkey pubKey.pem -pubin -verify -sigfile sig.sig
    

    Se for bem-sucedido, este comando devolve Signature Verified Successfully. Já pode validar o certificado.

  9. Extraia o certificado público para um ficheiro .pem:

    cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.certInfo.cert' > cert.pem
    
  10. Transfira o certificado de raiz (ca.crt no comando seguinte):

    curl -o ca.crt https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
    
  11. Valide o certificado com o certificado extraído e o certificado raiz:

    openssl verify -verbose -CAfile ca.crt cert.pem
    

    Se for bem-sucedido, este comando devolve cert.pem: OK.

Valide as assinaturas dos campos de metadados de segurança

Pode validar a assinatura dos seguintes campos no ficheiro de metadados de segurança de forma independente:

  • buildInfo
  • vexInfo
  • healthInfo (se presente)

Os dados nos campos têm hash aplicado com o algoritmo SHA-256 e, em seguida, o hash é assinado com o algoritmo ECDSAP256_DER. O certificado e a cadeia de certificados são fornecidos nos metadados para que possa validar a assinatura. Use o seguinte certificado de raiz para validar a cadeia de certificados:

https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt

Pode validar as assinaturas manualmente ou através da ferramenta de validação de OSS garantido.

Os passos seguintes descrevem como validar manualmente a assinatura do campo buildInfo no ficheiro metadata.json. Pode usar passos semelhantes para validar a assinatura do campo vexInfo ou do campo healthInfo.

Pode validar assinaturas através de várias ferramentas. O exemplo seguinte usa a CLI gcloud, o OpenSSL (versão 3.0.1 ou posterior) e o jq (1.7.1 ou posterior) para validar as assinaturas num sistema Linux.

  1. Gere o resumo SHA-256 do campo:

    cat metadata.json | jq -rj '.buildInfo' | sha256sum | cut -d ' ' -f1 > actualDigest.txt
    
  2. Extraia o resumo do campo fornecido no ficheiro metadata.json:

    cat metadata.json | jq -rj '.buildInfoSignature.digest[0].digest' | cut -d ':' -f2 > expectedDigest.txt
    
  3. Verifique se existem diferenças entre os dois resumos:

    diff actualDigest.txt expectedDigest.txt
    

    Se não houver diferença, não é apresentado nenhum resultado, o que é o caso ideal. Agora, pode validar a assinatura.

  4. Extraia o resumo do campo para um ficheiro .bin:

    cat metadata.json | jq -rj '.buildInfoSignature.digest[0].digest' | cut -d ':' -f2 | xxd -r -p > digest.bin
    
  5. Extraia a assinatura do resumo para um ficheiro .sig:

    cat metadata.json | jq -rj '.buildInfoSignature.signature[0].signature' | xxd -r -p > sig.sig
    
  6. Extraia a chave pública do certificado público para um ficheiro .pem:

    cat metadata.json | jq -rj '.buildInfoSignature.certInfo.cert' | openssl x509 -pubkey -noout  > pubKey.pem
    
  7. Valide a assinatura do resumo através da chave pública extraída:

    openssl pkeyutl -in digest.bin -inkey pubKey.pem -pubin -verify -sigfile sig.sig
    

    Se a validação for bem-sucedida, este comando devolve Signature Verified Successfully. Já pode validar o certificado.

  8. Extraia o certificado público para um ficheiro .pem:

    cat metadata.json | jq -rj '.buildInfoSignature.certInfo.cert' > cert.pem
    
  9. Transfira o certificado de raiz, denominado ca.crt no seguinte comando:

    curl -o ca.crt https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
    
  10. Valide o certificado com o certificado extraído e o certificado raiz:

    openssl verify -verbose -CAfile ca.crt cert.pem
    

    Se for bem-sucedido, o comando devolve cert.pem: OK.