synta 0.2.0

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# Quick Start

## Parse a DER-encoded certificate in 10 lines

```rust
use synta::{Decoder, Encoding};
use synta_certificate::{Certificate, format_dn};

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let der = std::fs::read("cert.der")?;

    let mut decoder = Decoder::new(&der, Encoding::Der);
    let cert: Certificate = decoder.decode()?;

    let subject = format_dn(cert.tbs_certificate.subject.as_bytes());
    println!("Subject: {}", subject);
    println!("Serial:  {:?}", cert.tbs_certificate.serial_number);
    Ok(())
}
```

## Decode and encode a basic INTEGER

```rust
use synta::{Decoder, Encoder, Encoding, Integer};

// Decode
let data = vec![0x02, 0x01, 0x2A]; // DER INTEGER 42
let mut decoder = Decoder::new(&data, Encoding::Der);
let integer: Integer = decoder.decode()?;
assert_eq!(integer.as_i64()?, 42);

// Encode
let value = Integer::from(12345i64);
let mut encoder = Encoder::new(Encoding::Der);
encoder.encode(&value)?;
let encoded = encoder.finish()?;
```

The same encode and decode can be written more concisely with the `ToDer` and
`FromDer` convenience traits:

```rust,ignore
use synta::{Integer, FromDer, ToDer};

// Decode
let data: &[u8] = &[0x02, 0x01, 0x2A];
let integer = Integer::from_der(data)?;
assert_eq!(integer.as_i64()?, 42);

// Encode
let encoded: Vec<u8> = Integer::from(12345i64).to_der()?;
```

See the [Encoder tutorial](../tutorial/encoding.md#quick-encode-with-toder) and
[Decoder tutorial](../tutorial/decoding.md#quick-decode-with-fromder) for full
details, including the `to_ber()` / `from_ber()` variants and the zero-copy
limitation for borrowed types.

## Build a SEQUENCE

```rust
use synta::types::constructed::{Element, Sequence};
use synta::types::primitive::{Boolean, Integer};
use synta::{Encoder, Encoding};

let mut seq = Sequence::new();
seq.push(Element::Integer(Integer::from(42)));
seq.push(Element::Boolean(Boolean::new(true)));

let mut encoder = Encoder::new(Encoding::Der);
encoder.encode(&seq)?;
let encoded = encoder.finish()?;
```

## Generate Rust types from an ASN.1 schema

Create `user.asn1`:

```asn1
UserModule DEFINITIONS ::= BEGIN

    UserId ::= INTEGER (1..999999)

    User ::= SEQUENCE {
        id       UserId,
        username IA5String,
        active   BOOLEAN
    }

END
```

Generate:

```bash
synta-codegen user.asn1 -o src/user.rs
```

Use the generated types:

```rust,ignore
// In src/user.rs — included automatically by build.rs or manually placed
use synta::{Decoder, Encoder, Encoding};

let user = User {
    id: UserId::new(42u32).unwrap(),
    username: synta::IA5String::new("alice".to_string()).unwrap(),
    active: synta::Boolean::new(true),
};

let mut encoder = Encoder::new(Encoding::Der);
encoder.encode(&user)?;
let encoded = encoder.finish()?;
let mut decoder = Decoder::new(&encoded, Encoding::Der);
let decoded: User = decoder.decode()?;
assert_eq!(user, decoded);
```

## Verify a TLS server certificate chain

```rust,ignore
use synta::{Decoder, Encoding};
use synta_certificate::{Certificate, OpensslSignatureVerifier};
use synta_x509_verification::{
    ops::VerificationCertificate,
    policy::{PolicyDefinition, Subject},
    trust_store::Store,
    types::DNSName,
    verify, RevocationChecks,
};
use std::time::{SystemTime, UNIX_EPOCH};

let root_der        = std::fs::read("root.der")?;
let intermediate_der = std::fs::read("intermediate.der")?;
let leaf_der        = std::fs::read("leaf.der")?;

fn parse<'a>(der: &'a [u8]) -> Certificate<'a> {
    Decoder::new(der, Encoding::Der).decode().unwrap()
}

let root        = VerificationCertificate::new(parse(&root_der),         &root_der);
let intermediate = VerificationCertificate::new(parse(&intermediate_der), &intermediate_der);
let leaf        = VerificationCertificate::new(parse(&leaf_der),         &leaf_der);

let store    = Store::new([root]);
let hostname = DNSName::new("example.com").unwrap();
let now      = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64;

let policy = PolicyDefinition::new_server(
    OpensslSignatureVerifier,
    vec![Subject::Dns(hostname)],
    now,
);

let chain = verify(&leaf, &[intermediate], &policy, &store, RevocationChecks::default())?;
println!("Verified chain of {} certificates", chain.len());
```

## Next steps

- [Tutorial: Decoding]../tutorial/decoding.md — step-by-step decode walkthrough
- [Tutorial: Encoding]../tutorial/encoding.md — building and encoding DER
- [Code Generation Overview]../codegen/overview.md — using `synta-codegen`
- [PKI: Certificate]../pki/certificate.md`synta-certificate` API