Skip to content

Commit

Permalink
Merge pull request #403 from jku/verify_blob-change-cert-arg
Browse files Browse the repository at this point in the history
cosign: Make verify-blob compatible with sigstore-python
  • Loading branch information
flavio authored Oct 22, 2024
2 parents 170a765 + 2ca912d commit 8b965f4
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 6 deletions.
11 changes: 9 additions & 2 deletions examples/cosign/verify-blob/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

extern crate clap;
extern crate sigstore;
use base64::{engine::general_purpose::STANDARD as BASE64_STD_ENGINE, Engine as _};
use clap::Parser;
use sigstore::cosign::client::Client;
use sigstore::cosign::CosignCapabilities;
Expand Down Expand Up @@ -56,11 +57,17 @@ pub async fn main() {
.with(fmt::layer().with_writer(std::io::stderr))
.init();

let certificate = fs::read_to_string(&cli.certificate).expect("error reading certificate");
// certificate may be PEM or "double base64 encoded PEM" (cosign).
let cert_input = fs::read_to_string(&cli.certificate).expect("error reading certificate");
let certificate = match BASE64_STD_ENGINE.decode(cert_input.clone()) {
Ok(res) => String::from_utf8(res).expect("error stringifying PEM certificate"),
Err(_) => cert_input,
};

let signature = fs::read_to_string(&cli.signature).expect("error reading signature");
let blob = fs::read(cli.blob.as_str()).expect("error reading blob file");

match Client::verify_blob(&certificate, &signature, &blob) {
match Client::verify_blob(&certificate, signature.trim(), &blob) {
Ok(_) => println!("Verification succeeded"),
Err(e) => eprintln!("Verification failed {:?}", e),
}
Expand Down
10 changes: 9 additions & 1 deletion examples/cosign/verify-bundle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use base64::{engine::general_purpose::STANDARD as BASE64_STD_ENGINE, Engine as _};
use clap::Parser;
use sigstore::cosign::bundle::SignedArtifactBundle;
use sigstore::cosign::client::Client;
Expand Down Expand Up @@ -62,7 +63,14 @@ pub async fn main() {
let blob = fs::read(cli.blob.as_str()).expect("error reading blob file");

let bundle = SignedArtifactBundle::new_verified(&bundle_json, &rekor_pub_key).unwrap();
match Client::verify_blob(&bundle.cert, &bundle.base64_signature, &blob) {

// certificate in bundle is double base64 encoded, remove one layer:
let cert_data = BASE64_STD_ENGINE
.decode(bundle.cert)
.expect("Error decoding base64 certificate");
let cert = String::from_utf8(cert_data).expect("error stringifying PEM certificate");

match Client::verify_blob(&cert, &bundle.base64_signature, &blob) {
Ok(_) => println!("Verification succeeded"),
Err(e) => eprintln!("Verification failed: {}", e),
}
Expand Down
5 changes: 2 additions & 3 deletions src/cosign/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ use crate::registry::{Auth, PushResponse};

use crate::crypto::{CosignVerificationKey, Signature};
use crate::errors::SigstoreError;
use base64::{engine::general_purpose::STANDARD as BASE64_STD_ENGINE, Engine as _};
use pkcs8::der::Decode;
use x509_cert::Certificate;

Expand Down Expand Up @@ -155,13 +154,13 @@ pub trait CosignCapabilities {
/// Verifies the signature produced by cosign when signing the given blob via the `cosign sign-blob` command
///
/// The parameters:
/// * `cert`: a PEM encoded x509 certificate that contains the public key used to verify the signature
/// * `cert`: a PEM encoded x509 certificate that contains the public key used to verify the signature.
/// Note that cert is not double-base64-encoded like the output of sigstore/cosign is.
/// * `signature`: the base64 encoded signature of the blob that has to be verified
/// * `blob`: the contents of the blob
///
/// This function returns `Ok())` when the given signature has been verified, otherwise returns an `Err`.
fn verify_blob(cert: &str, signature: &str, blob: &[u8]) -> Result<()> {
let cert = BASE64_STD_ENGINE.decode(cert)?;
let pem = pem::parse(cert)?;
let cert = Certificate::from_der(pem.contents()).map_err(|e| {
SigstoreError::PKCS8SpkiError(format!("parse der into cert failed: {e}"))
Expand Down

0 comments on commit 8b965f4

Please sign in to comment.