synta 0.1.11

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# CSR, CRL, and OCSP

## Certificate Signing Request (CSR / PKCS#10)

The `csr` module exposes `CertificationRequest` (RFC 2986):

```rust,ignore
use synta::{Decoder, Encoding};
use synta_certificate::csr::CertificationRequest;

let der = std::fs::read("request.csr")?;
let mut dec = Decoder::new(&der, Encoding::Der);
let csr: CertificationRequest = dec.decode()?;

let info = &csr.certification_request_info;
println!("Subject: {:?}", info.subject);
println!("Version: {:?}", info.version);
```

### Building a CSR (openssl feature)

```rust,ignore
use synta_certificate::{CsrBuilder, OpensslCertificateSigner};

let subject_der: &[u8] = /* DER-encoded Name SEQUENCE */;
let spki_der:    &[u8] = /* DER-encoded SubjectPublicKeyInfo */;
let pkey: openssl::pkey::PKey<_> = /* OpenSSL private key */;

let signer = OpensslCertificateSigner::new(&pkey, "sha256");

let csr_der: Vec<u8> = CsrBuilder::new()
    .subject_name(subject_der)
    .public_key_der(spki_der)
    .sign(&signer)
    .expect("CSR signing failed");
```

## Certificate Revocation List (CRL)

The `crl` module exposes `CertificateList` (RFC 5280 §5):

```rust,ignore
use synta::{Decoder, Encoding};
use synta_certificate::crl::CertificateList;

let der = std::fs::read("revoked.crl")?;
let mut dec = Decoder::new(&der, Encoding::Der);
let crl: CertificateList = dec.decode()?;

let tbs = &crl.tbs_cert_list;
println!("Issuer: {:?}", tbs.issuer);
println!("This update: {:?}", tbs.this_update);
println!("Next update: {:?}", tbs.next_update);

let revoked_count = tbs.revoked_certificates
    .as_ref()
    .map_or(0, |v| v.len());
println!("Revoked entries: {}", revoked_count);
```

## OCSP Response

The `ocsp` module exposes `OCSPResponse` (RFC 6960):

```rust,ignore
use synta::{Decoder, Encoding};
use synta_certificate::ocsp::OCSPResponse;

let der = std::fs::read("response.der")?;
let mut dec = Decoder::new(&der, Encoding::Der);
let resp: OCSPResponse = dec.decode()?;

println!("Status: {:?}", resp.response_status);
if let Some(rb) = &resp.response_bytes {
    println!("Response type OID: {:?}", rb.response_type);
}
```

## PKCS#7 / CMS certificate extraction

`certs_from_pkcs7` extracts DER-encoded certificates from a PKCS#7 `SignedData`
bundle (RFC 5652).  Both DER and BER input are accepted:

```rust,ignore
use synta_certificate::certs_from_pkcs7;

let p7b = std::fs::read("bundle.p7b")?;
let certs: Vec<Vec<u8>> = certs_from_pkcs7(&p7b)?;
println!("Found {} certificate(s)", certs.len());
```

## PKCS#12 certificate and key extraction

`certs_from_pkcs12` extracts certificates from a PKCS#12 PFX archive.
Pass `NoCrypto` to reject encrypted bags:

```rust,ignore
use synta_certificate::{certs_from_pkcs12, NoCrypto};

let pfx = std::fs::read("keystore.p12")?;
let certs: Vec<Vec<u8>> = certs_from_pkcs12(&pfx, b"password", &NoCrypto)?;
```

With the `openssl` feature, encrypted bags (PBES2/PBKDF2 + AES, or legacy
RC2/3DES) can be decrypted:

```rust,ignore
use synta_certificate::{certs_from_pkcs12, OpensslDecryptor};

let certs = certs_from_pkcs12(&pfx, b"secret", &OpensslDecryptor)?;
```

`keys_from_pkcs12` extracts `OneAsymmetricKey` (PKCS#8, RFC 5958) blobs:

```rust,ignore
use synta_certificate::{keys_from_pkcs12, OpensslDecryptor};

let keys: Vec<Vec<u8>> = keys_from_pkcs12(&pfx, b"secret", &OpensslDecryptor)?;
```

## Building a PKCS#12 archive

```rust,ignore
use synta_certificate::{Pkcs12Builder, OpensslPkcs12Encryptor, NoPkcs12Encryptor};

// With OpenSSL encryption (PBES2/PBKDF2-SHA256, AES-256-CBC)
let pfx_der: Vec<u8> = Pkcs12Builder::new()
    .certificate(&cert_der)
    .private_key(&key_der)
    .build(b"s3cr3t", &OpensslPkcs12Encryptor::new())
    .expect("PKCS#12 build failed");

// Without encryption
let pfx_der: Vec<u8> = Pkcs12Builder::new()
    .certificate(&cert_der)
    .build(b"", &NoPkcs12Encryptor)
    .expect("PKCS#12 build failed");
```

## Generated modules

| Schema | Generated module | Standard |
|--------|-----------------|----------|
| `asn1/X509-CRL.asn1` | `crl` | RFC 5280 §5 |
| `asn1/PKCS10-CSR.asn1` | `csr` | RFC 2986 |
| `asn1/OCSP.asn1` | `ocsp` | RFC 6960 |
| `asn1/PKCS7-CMS.asn1` | `pkcs7_types` | RFC 5652 |
| `asn1/PKCS12.asn1` | `pkcs12_types` | RFC 7292 |
| `asn1/PKCS8.asn1` | `pkcs8_types` | RFC 5958 |