osslsigncode 0.1.1

In-process Rust bindings for the vendored osslsigncode Authenticode implementation
# osslsigncode

This is a safe (hopefully), Rust API for Authenticode. 

Sign, verify, inspect, and strip signatures on PE/CAB/MSI/APPX and script files.

Bindings against [osslsigncode](https://github.com/mtrojnar/osslsigncode), which doesn't provide a library, so please ping me if things start breaking, and I'll update!

```rust
use osslsigncode::{Credential, Digest, Secret, TrustAnchors, Unsigned};
use std::path::Path;

let root = Path::new(env!("CARGO_MANIFEST_DIR"));
let dir = tempfile::tempdir().unwrap();
let input = root.join("vendor/osslsigncode/tests/files/unsigned.js");
let credential = Credential::pkcs12(root.join("tests/fixtures/publisher.p12"), Secret::value("secret"));

let signed = Unsigned::open(&input)?
    .sign(credential)
    .digest(Digest::Sha256)
    .output(dir.path().join("app-signed.js"))
    .sign()?;

signed
    .verify()
    .trust(TrustAnchors {
        ca_file: Some(root.join("tests/fixtures/ca.pem")),
        ..Default::default()
    })
    .ignore_timestamp()
    .check()?;
# Ok::<(), osslsigncode::Error>(())
```

## Extracting and inspecting

```rust
# use osslsigncode::{Credential, Digest, Secret, Unsigned};
# use std::path::Path;
# let root = Path::new(env!("CARGO_MANIFEST_DIR"));
# let dir = tempfile::tempdir().unwrap();
# let input = root.join("vendor/osslsigncode/tests/files/unsigned.js");
# let credential = Credential::pkcs12(root.join("tests/fixtures/publisher.p12"), Secret::value("secret"));
# let signed = Unsigned::open(&input)?.sign(credential).digest(Digest::Sha256).output(dir.path().join("signed.js")).sign()?;
use std::io::Read;

let mut sig = Vec::new();
signed.extract_signature().pem().reader()?.read_to_end(&mut sig).unwrap();
assert!(sig.starts_with(b"-----BEGIN"));

// Inspect the embedded signature without asserting trust.
let info = signed.inspect()?;
assert_eq!(info.digest, Some(Digest::Sha256));
assert!(info.signers[0].subject.contains("CN="));

let unsigned = signed.strip().output(dir.path().join("stripped.js")).strip()?;
assert_eq!(std::fs::read(unsigned.path()).unwrap(), std::fs::read(&input).unwrap());
# Ok::<(), osslsigncode::Error>(())
```

## Builder completeness

```rust
use osslsigncode::{Credential, Digest, Secret, Timestamp, Unsigned};
use std::path::Path;

let root = Path::new(env!("CARGO_MANIFEST_DIR"));
let input = root.join("vendor/osslsigncode/tests/files/unsigned.js");
let credential = Credential::pkcs12(root.join("tests/fixtures/publisher.p12"), Secret::value("secret"));

let _ready = Unsigned::open(&input)
    .unwrap()
    .sign(credential)
    .digest(Digest::Sha256)
    .timestamp(Timestamp::rfc3161("http://timestamp.example"))
    .output("builder-only.js");
// `_ready.sign()` would run the job; omitting it still type-checks `Ready`.
```

## Using from another crate

```toml
[dependencies]
osslsigncode = "0.2.0"
```

Clone with submodules. You need a C compiler, libclang (bindgen), and Perl
when the `vendored` OpenSSL feature is enabled.

## License

The vendored upstream implementation is licensed under the GNU General Public
License, version 3 or later, with an OpenSSL linking exception. See
[LICENSE](./LICENSE) and
[`vendor/osslsigncode/LICENSE.txt`](vendor/osslsigncode/LICENSE.txt).
The compiled submodule revision is exported as `VENDOR_COMMIT`.