voa-openpgp 0.2.0

A library for using OpenPGP verifiers in VOA
Documentation
# VOA-OpenPGP

A library for using [OpenPGP] verifiers in [VOA].

⚠️ **DO NOT USE IN PRODUCTION**: This VOA backend is still in an early experimental development stage.

See <https://uapi-group.org/specifications/specs/file_hierarchy_for_the_verification_of_os_artifacts/#openpgp>

## Documentation

- <https://voa.archlinux.page/rustdoc/voa_openpgp/> for development version of the crate
- <https://docs.rs/voa-openpgp/latest/voa_openpgp/> for released versions of the crate

## Examples

### Import

[OpenPGP certificates] can be written to their dedicated directory structures in a [VOA] hierarchy.

It is supported to import single binary or [ASCII-armored] files, as well as directory structures that contain a number of [OpenPGP packet] files which comprise an OpenPGP certificate when concatenated (this structured form is in use by the [archlinux-keyring] project).

```rust
use voa_core::VerifierWriter;
use voa_openpgp::OpenPgpImport;
# use pgp::{
#     composed::{KeyType, SecretKeyParamsBuilder, SignedPublicKey, SubkeyParamsBuilder},
#     ser::Serialize,
#     types::Password,
# };
# use rand::thread_rng;
use tempfile::{NamedTempFile, tempdir};
#
# fn openpgp_cert() -> testresult::TestResult<SignedPublicKey> {
#     let mut signkey = SubkeyParamsBuilder::default();
#     signkey
#         .key_type(KeyType::Ed25519Legacy)
#         .can_sign(true)
#         .can_encrypt(false)
#         .can_authenticate(false);
#     let mut key_params = SecretKeyParamsBuilder::default();
#     key_params
#         .key_type(KeyType::Ed25519Legacy)
#         .can_certify(true)
#         .can_sign(false)
#         .can_encrypt(false)
#         .primary_user_id("John Doe <jdoe@example.org>".to_string())
#         .subkeys(vec![signkey.build()?]);
#
#     let secret_key_params = key_params.build()?;
#     let secret_key = secret_key_params.generate(thread_rng())?;
#
#     // Produce binding self-signatures that link all the components together
#     let signed = secret_key.sign(&mut thread_rng(), &Password::from(""))?;
#
#     let pubkey = SignedPublicKey::from(signed);
#     Ok(pubkey)
# }
# fn main() -> testresult::TestResult {

// Write a generic OpenPGP certificate to a temporary file.
let mut temp_file = NamedTempFile::new()?;
openpgp_cert()?.to_writer(&mut temp_file)?;
let input_path = temp_file.path();

// Import the OpenPGP certificate.
let import = OpenPgpImport::from_file(input_path)?;

// Prepare a temporary output directory.
let temp_dir = tempdir()?;
let output_dir = temp_dir.path();

// Write the OpenPGP verifier to a VOA hierarchy in the temporary output directory.
//
// There, the verifier is written to the configured directory, e.g.
// `os/purpose/context/openpgp/f1d2d2f924e986ac86fdf7b36c94bcdf32beec15.openpgp`
import.write_to_hierarchy(
    output_dir,
    "os".parse()?,
    "purpose".parse()?,
    Some("context".parse()?),
)?;

assert!(
    output_dir
        .join("os")
        .join("purpose")
        .join("context")
        .join("openpgp")
        .join(import.file_name())
        .exists()
);
# Ok(())
# }
```

### Verification

⚠️ **DO NOT USE IN PRODUCTION**: The verification mechanism in this VOA backend is still in an early experimental development stage.

Simple verification of artifacts using one or more OpenPGP signatures and verifiers from VOA is straight forward:

```rust no_run
use std::path::PathBuf;
use voa_openpgp::{verify_from_file, OpenpgpCert, OpenpgpSignature, VoaOpenpgp};

# fn main() -> testresult::TestResult {
let voa = VoaOpenpgp::new();
let certs = voa.lookup("os".parse()?, "purpose".parse()?, "context".parse()?);
let cert_refs: Vec<&OpenpgpCert> = certs.iter().collect();

verify_from_file(
    &PathBuf::from("/path/to/a/file.tar.zst"),
    &cert_refs,
    &[&OpenpgpSignature::from_file(&PathBuf::from("/path/to/a/file.tar.zst.sig"))?],
)?;

# Ok(())
# }
```

## Contributing

Please refer to the [contribution guidelines] to learn how to contribute to this project.

## License

This project can be used under the terms of the [Apache-2.0] or [MIT].
Contributions to this project, unless noted otherwise, are automatically licensed under the terms of both of those licenses.

[ASCII-armored]: https://openpgp.dev/book/armor.html
[Apache-2.0]: ../LICENSES/Apache-2.0.txt
[MIT]: ../LICENSES/MIT.txt
[OpenPGP certificates]: https://openpgp.dev/book/certificates.html
[OpenPGP packet]: https://openpgp.dev/book/zoom/certificates.html
[OpenPGP]: https://www.rfc-editor.org/rfc/rfc9580
[VOA]: https://uapi-group.org/specifications/specs/file_hierarchy_for_the_verification_of_os_artifacts/
[archlinux-keyring]: https://gitlab.archlinux.org/archlinux/archlinux-keyring/
[contribution guidelines]: ../CONTRIBUTING.md