Accéder aux métadonnées de sécurité et valider les packages

Ce document explique comment accéder aux métadonnées de sécurité du bucket Cloud Storage assuredoss-metadata. Pour obtenir une description des métadonnées de sécurité, consultez Champs de métadonnées de sécurité.

Ce document ne s'applique qu'au niveau premium d'Assured OSS. Pour le niveau sans frais, consultez Valider les signatures dans le niveau sans frais Assured OSS.

Avant de commencer

  1. Intégrer Assured OSS avec Security Command Center

  2. Validez la connectivité à Assured OSS pour les comptes de service demandés.

Extraire les métadonnées

Vous pouvez utiliser des commandes gcloud ou curl pour télécharger les métadonnées. Créez l'URL pour les deux en utilisant les informations suivantes :

  • Langage : java, python, golang ou javascript. La valeur doit être en minuscules.
  • Package_ID : l'une des valeurs suivantes :

    • Java : groupId:artifactId
    • Python : packageName
    • JavaScript : @org-name/package-name, @username/package-name ou package-name
    • Go : packageName

    La valeur doit être en minuscules.

  • Version : version du package.

L'URL doit respecter le format suivant :

gcloud

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

L'URL doit être en minuscules.

Voici quelques exemples d'URL :

  • Exemple d'URL Python : gs://assuredoss-metadata/python/blessed/1.20.0/metadata.json

  • Exemple d'URL Java : gs://assuredoss-metadata/java/org.apache.logging.log4j:log4j-core/2.17.1/metadata.json

  • Exemple d'URL JavaScript : gs://assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json

  • Exemple d'URL Go : 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

L'URL doit être en minuscules.

Voici quelques exemples d'URL :

  • Exemple d'URL Python : https://storage.googleapis.com/assuredoss-metadata/python/blessed/1.20.0/metadata.json

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

  • Exemple d'URL JavaScript : https://storage.googleapis.com/assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json

  • Exemple d'URL Go : https://storage.googleapis.com/assuredoss-metadata/golang/github.com/rs/zerolog/1.9.1/metadata.json

  1. Téléchargez les métadonnées :

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

Vous pouvez maintenant valider les signatures. Vous disposez de deux options :

Vérifier les signatures des packages téléchargés à l'aide de l'outil aoss-verifier

Utilisez l'outil aoss-verifier pour valider les métadonnées de package.

Avant d'utiliser cet outil, installez Go.

  1. Installez l'outil aoss-verifier.

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

  3. Exécutez la commande 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]
    

    Remplacez les éléments suivants :

    • TYPE : les valeurs possibles sont premiuminfo.
    • LANGUAGE : langage du package. La valeur doit être en minuscules.
    • PACKAGE_ID : pour Java, le format est groupId:artifactId. Pour Python et Go, le format est packageName. La valeur doit être en minuscules.
    • VERSION : version du package.

    --disable_certificate_verification est un flag facultatif qui permet d'ignorer la mise en correspondance du certificat d'entité finale avec le certificat racine via la chaîne de certificats, le cas échéant.

    --temp_downloads_path est un flag facultatif permettant de définir le chemin d'accès du dossier dans lequel vous souhaitez télécharger les fichiers (remplacez TEMP_DOWNLOADS_DIR_PATH). Si ce flag n'est pas défini, les fichiers sont téléchargés dans le dossier tmp_downloads du répertoire actuel.

    --disable_deletes est un flag facultatif qui permet de conserver les fichiers téléchargés. Par défaut, l'outil nettoie tous les fichiers téléchargés.

Pour plus d'informations, consultez le fichier README.

Valider manuellement les signatures des packages téléchargés

Vous ne pouvez valider la signature d'artefact que pour les binaires créés de manière sécurisée par Assured OSS, et non pour ceux fournis par Assured OSS via des proxys.

Pour valider manuellement les signatures, vous pouvez utiliser différents outils. La procédure suivante utilise la gcloud CLI, OpenSSL (version 3.0.1 ou ultérieure) et jq (version 1.7.1 ou ultérieure) pour valider les signatures sous Linux.

  1. Téléchargez le fichier de métadonnées. Comme décrit dans Champs de métadonnées de sécurité, le fichier de métadonnées comporte un champ SBOM inclus dans le champ buildInfo. La nomenclature logicielle (SBOM) contient l'artefact (par exemple, un fichier JAR ou EGG) qui a été créé avec une annotation représentant la signature. Cet artefact vous permet de déterminer l'ID SPDX.

    Par exemple, si le nom de l'artefact est artifact_name, l'ID spdx_id est SPDXRef-Package-artifact_name. Pour valider un package nommé gradio-3.30.0-py3-none-any.whl, l'ID spdx_id est SPDXRef-Package-gradio-3.30.0-py3-none-any.whl.

  2. Extrayez le condensé SHA-256 du fichier de métadonnées :

    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
    

    Remplacez les éléments suivants :

    • METADATA_FILENAME : nom de votre fichier de métadonnées de sécurité.

    • SPDX_ID : identifiant SPDX.

  3. Calculez le condensé de l'artefact :

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

    Remplacez ARTIFACT_FILE par le nom du fichier d'artefact.

  4. Vérifiez s'il existe des différences entre les deux :

    diff actualDigest.txt expectedDigest.txt
    

    S'il n'existe aucune différence, aucun résultat n'est généré.

  5. Extrayez le condensé du champ dans un fichier .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. Extrayez la signature du condensé dans un fichier .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. Extrayez la clé publique du certificat public dans un fichier .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. Validez la signature du condensé à l'aide de la clé publique extraite :

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

    Si la commande est bien exécutée, elle renvoie Signature Verified Successfully. Vous pouvez maintenant valider le certificat.

  9. Extrayez le certificat public dans un fichier .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. Téléchargez le certificat racine (ca.crt dans la commande suivante) :

    curl -o ca.crt https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
    
  11. Validez le certificat à l'aide du certificat extrait et du certificat racine :

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

    Si la commande est bien exécutée, elle renvoie cert.pem: OK.

Vérifier les signatures pour les champs de métadonnées de sécurité

Vous pouvez vérifier la signature des champs suivants de manière indépendante dans le fichier de métadonnées de sécurité :

  • buildInfo
  • vexInfo
  • healthInfo (si disponible)

Les données contenues dans les champs sont hachées avec SHA-256, puis le hachage est signé à l'aide de l'algorithme ECDSAP256_DER. Le certificat et la chaîne de certificats sont fournis dans les métadonnées pour que vous puissiez vérifier la signature. Utilisez le certificat racine suivant pour valider la chaîne de certificats :

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

Vous pouvez valider les signatures manuellement, ou à l'aide de l'outil de validation Assured OSS.

Les étapes suivantes décrivent comment valider manuellement la signature du champ buildInfo dans le fichier metadata.json. Vous pouvez suivre une procédure similaire pour valider la signature du champ vexInfo ou healthInfo.

Vous pouvez valider les signatures à l'aide de différents outils. L'exemple suivant utilise la gcloud CLI, OpenSSL (version 3.0.1 ou ultérieure) et jq (version 1.7.1 ou ultérieure) pour valider les signatures sur un système Linux.

  1. Générez le condensé SHA-256 du champ :

    cat metadata.json | jq -rj '.buildInfo' | sha256sum | cut -d ' ' -f1 > actualDigest.txt
    
  2. Extrayez le condensé du champ fourni dans le fichier metadata.json :

    cat metadata.json | jq -rj '.buildInfoSignature.digest[0].digest' | cut -d ':' -f2 > expectedDigest.txt
    
  3. Vérifiez s'il existe des différences entre les deux condensés :

    diff actualDigest.txt expectedDigest.txt
    

    S'il n'existe aucune différence, aucun résultat ne sera généré, ce qui représente un cas idéal. Vous pouvez maintenant valider la signature.

  4. Extrayez le condensé du champ dans un fichier .bin :

    cat metadata.json | jq -rj '.buildInfoSignature.digest[0].digest' | cut -d ':' -f2 | xxd -r -p > digest.bin
    
  5. Extrayez la signature du condensé dans un fichier .sig :

    cat metadata.json | jq -rj '.buildInfoSignature.signature[0].signature' | xxd -r -p > sig.sig
    
  6. Extrayez la clé publique du certificat public dans un fichier .pem :

    cat metadata.json | jq -rj '.buildInfoSignature.certInfo.cert' | openssl x509 -pubkey -noout  > pubKey.pem
    
  7. Validez la signature du condensé à l'aide de la clé publique extraite :

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

    Si la validation réussit, cette commande renvoie Signature Verified Successfully. Vous pouvez maintenant valider le certificat.

  8. Extrayez le certificat public dans un fichier .pem :

    cat metadata.json | jq -rj '.buildInfoSignature.certInfo.cert' > cert.pem
    
  9. Téléchargez le certificat racine, nommé ca.crt dans la commande suivante :

    curl -o ca.crt https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
    
  10. Validez le certificat à l'aide du certificat extrait et du certificat racine :

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

    Si la commande est bien exécutée, elle renvoie cert.pem: OK.