synta 0.1.8

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# API Reference for Rust Crates

<style>
  /* Remove content padding and width cap so the iframe fills edge-to-edge */
  .content main { padding: 0 !important; max-width: none !important; }
</style>

<iframe
  src="api/synta/index.html"
  style="width:100%; height:calc(100vh - var(--menu-bar-height, 50px)); border:none; display:block;"
  title="Synta Rust API Reference (rustdoc)">
</iframe>

> If the frame above is empty, build the documentation first:
> ```bash
> bash contrib/ci/local-ci.sh doc
> ```

---

## PKCS#11 URI Key Loading

The functions and types described below are part of `synta-certificate` and
allow loading private keys directly from PKCS#11 hardware or software tokens
without ever extracting key material into process memory.

### `BackendPrivateKey::from_pkcs11_uri`

```rust
pub fn from_pkcs11_uri(uri: &str) -> Result<Self, PrivateKeyError>
```

Loads a private key from a PKCS#11 token identified by the given RFC 7512
`pkcs11:` URI.  The URI must begin with the `pkcs11:` scheme.

The key handle (or, for the NSS backend, the slot reference) is stored inside
the returned `BackendPrivateKey`.  Key material is never extracted; all signing
operations are delegated to the token.

**When to use it:** Use `from_pkcs11_uri` instead of `from_pem` or
`from_pkcs8_der` whenever the private key resides in an HSM, smart card, or
software token and must not leave the token boundary.

**Backend-specific requirements:**

| Backend | Mandatory URI attributes | Prerequisites |
|---------|--------------------------|--------------|
| OpenSSL (`openssl` feature) | None | `pkcs11-provider` configured via `OPENSSL_CONF` before the call |
| NSS (`nss` feature) | `token=` and `object=` | PKCS#11 module registered via `modutil` before the call |

See [deployment-guide.md](deployment-guide.md#hsm--pkcs11-key-storage) for
step-by-step setup instructions for each backend.

### `BackendPrivateKey::pkcs11_info`

```rust
pub fn pkcs11_info(&self) -> Option<&Pkcs11Uri>
```

Returns the parsed PKCS#11 URI for keys loaded via `from_pkcs11_uri`, or
`None` for software keys loaded from PEM/DER.

Useful for logging, diagnostics, or conditional logic that must behave
differently for HSM-backed keys.

### `Pkcs11Uri`

```rust
pub struct Pkcs11Uri {
    pub raw: String,              // verbatim URI string as supplied to from_pkcs11_uri
    pub attrs: Pkcs11UriAttributes,
}
```

Parsed representation of an RFC 7512 `pkcs11:` URI.  The `raw` field preserves
the original string exactly; `attrs` contains the pre-decoded path and query
attributes.

### `Pkcs11UriAttributes`

```rust
pub struct Pkcs11UriAttributes {
    pub token:     Option<String>,   // token= path attribute (slot/token label)
    pub object:    Option<String>,   // object= path attribute (key nickname/label)
    pub id:        Option<Vec<u8>>,  // id= CKA_ID, percent-decoded raw bytes
    pub pin_value: Option<String>,   // ?pin-value= query attribute (token PIN)
}
```

Pre-decoded path and query attributes extracted from a `pkcs11:` URI.

### URI format example

```
pkcs11:token=MyHSM;object=cakey;type=private?pin-value=1234
```

- `token=MyHSM` — the token label (mandatory for NSS, optional for OpenSSL)
- `object=cakey` — the key label / nickname (mandatory for NSS, optional for OpenSSL)
- `type=private` — selects the private-key object class (recommended)
- `pin-value=1234` — PIN supplied inline; omit if the token is already authenticated

### Note on key material

`BackendPrivateKey::pkcs8_der` is always empty for HSM-backed keys.  The token
handle is stored internally and used for every signing operation.  Callers
should never attempt to serialise an HSM key via `pkcs8_der`.

---

## RSA Key Transport

`BackendPublicKey` and `BackendPrivateKey` in `synta-certificate` expose
RSA encryption and decryption operations.  These are used in CMS
`EnvelopedData` construction (key transport RecipientInfo) and in any other
protocol that requires wrapping a symmetric key with an RSA public key.

Both backends (OpenSSL and NSS) are supported.  When both features are enabled,
OpenSSL takes priority.

### `BackendPublicKey::rsa_oaep_encrypt`

```rust
pub fn rsa_oaep_encrypt(
    &self,
    plaintext: &[u8],
    hash_alg: &str,
) -> Result<Vec<u8>, PrivateKeyError>
```

RSA-OAEP encryption using the recipient's public key.

`hash_alg` is the OAEP hash algorithm name: `"sha1"`, `"sha224"`,
`"sha256"`, `"sha384"`, or `"sha512"`.

Returns the ciphertext (same byte-length as the RSA modulus).

### `BackendPublicKey::rsa_pkcs1v15_encrypt`

```rust
pub fn rsa_pkcs1v15_encrypt(
    &self,
    plaintext: &[u8],
) -> Result<Vec<u8>, PrivateKeyError>
```

RSA PKCS#1 v1.5 encryption using the recipient's public key.  For new
protocols prefer RSA-OAEP; PKCS#1 v1.5 is supported for compatibility with
legacy CMS content.

Returns the ciphertext (same byte-length as the RSA modulus).

### `BackendPrivateKey::rsa_oaep_decrypt`

```rust
pub fn rsa_oaep_decrypt(
    &self,
    ciphertext: &[u8],
    hash_alg: &str,
) -> Result<Vec<u8>, PrivateKeyError>
```

RSA-OAEP decryption using the recipient's private key.

`hash_alg` must match the algorithm used during encryption.

### `BackendPrivateKey::rsa_pkcs1v15_decrypt`

```rust
pub fn rsa_pkcs1v15_decrypt(
    &self,
    ciphertext: &[u8],
) -> Result<Vec<u8>, PrivateKeyError>
```

RSA PKCS#1 v1.5 decryption using the recipient's private key.

**Backend notes:**

| Backend | Implementation |
|---------|----------------|
| OpenSSL (`openssl` feature) | Uses `EVP_PKEY_CTX_set_rsa_padding` / `EVP_PKEY_decrypt` |
| NSS (`nss` feature, no `openssl`) | Imports the public key via `SECKEY_DecodeDERSubjectPublicKeyInfo` and the private key via `PK11_ImportDERPrivateKeyInfoAndReturnKey` into the NSS internal softokn slot, then calls `PK11_PubEncrypt` / `PK11_PrivDecrypt` |