# PKI Workflow
This tutorial walks through a complete PKI workflow using `synta-certificate`:
parsing a certificate, checking a CRL, and inspecting an OCSP response.
## Adding the dependency
```toml
[dependencies]
synta-certificate = "0.1"
synta = "0.1"
```
The `openssl` feature is enabled by default, so no extra flags are needed for
certificate building and chain verification. To use the NSS backend instead:
```toml
[dependencies]
synta-certificate = { version = "0.1", default-features = false, features = ["std", "derive", "nss"] }
```
## Parsing a certificate
```rust,ignore
use synta::{Decoder, Encoding};
use synta_certificate::{Certificate, format_dn, identify_signature_algorithm};
let der = std::fs::read("cert.der")?;
let mut decoder = Decoder::new(&der, Encoding::Der);
let cert: Certificate = decoder.decode()?;
let tbs = &cert.tbs_certificate;
// Serial number (eagerly decoded)
println!("Serial: {:?}", tbs.serial_number);
// Issuer and subject are stored as zero-copy RawDer<'a> spans
let issuer_str = format_dn(tbs.issuer.as_bytes());
let subject_str = format_dn(tbs.subject.as_bytes());
println!("Issuer: {}", issuer_str);
println!("Subject: {}", subject_str);
// Signature algorithm
let alg_name = identify_signature_algorithm(&cert.signature_algorithm.algorithm);
println!("Algorithm: {}", alg_name);
```
## Subject Alternative Names
```rust,ignore
use synta_certificate::Certificate;
let cert: Certificate = /* ... */;
for (tag, content) in cert.subject_alt_names() {
match tag {
2 => println!("DNS: {}", String::from_utf8_lossy(&content)),
7 if content.len() == 4 => {
let octets: [u8; 4] = content.try_into().unwrap();
println!("IP: {}", std::net::Ipv4Addr::from(octets));
}
1 => println!("Email: {}", String::from_utf8_lossy(&content)),
_ => println!("tag={} len={}", tag, content.len()),
}
}
```
## Parsing DN attributes
```rust,ignore
use synta_certificate::parse_name_attrs;
let attrs = parse_name_attrs(cert.tbs_certificate.subject.as_bytes());
for (oid, value) in &attrs {
println!("{} = {}", oid, value);
}
// e.g. "2.5.4.3 = example.com", "2.5.4.10 = Example Inc"
```
## PEM encoding and decoding
```rust,ignore
use synta_certificate::{pem_to_der, der_to_pem};
// Decode: may contain multiple blocks (e.g. a certificate chain)
let pem_bytes = std::fs::read("chain.pem")?;
let ders: Vec<Vec<u8>> = pem_to_der(&pem_bytes);
// Encode: standard RFC 7468 format, 64-char lines
let pem_output = der_to_pem("CERTIFICATE", &der_bytes);
std::fs::write("cert.pem", &pem_output)?;
```
## Parsing a CRL
```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;
let issuer_str = format_dn(tbs.issuer.as_bytes());
println!("CRL issuer: {}", issuer_str);
println!("This update: {:?}", tbs.this_update);
let revoked = tbs.revoked_certificates.as_ref().map_or(0, |v| v.len());
println!("Revoked entries: {}", revoked);
```
## Parsing a CSR
```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);
```
## Parsing an OCSP response
```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);
}
```
## Generating a key and building a certificate
`PrivateKeyBuilder` generates keys through the active backend without exposing
backend-specific types. It works with both the `openssl` and `nss` features:
```rust,ignore
use synta::{Integer, UtcTime};
use synta_certificate::{CertificateBuilder, PrivateKeyBuilder, x509_types::Time};
let issuer_der: &[u8] = /* DER-encoded Name SEQUENCE */;
let subject_der: &[u8] = /* DER-encoded Name SEQUENCE */;
// Generate a P-256 key — no backend type appears in caller code
let key = PrivateKeyBuilder::ec("P-256").generate().expect("key gen failed");
let spki_der = key.public_key_spki_der().expect("SPKI failed");
let signer = key.as_signer("sha256");
let cert_der: Vec<u8> = CertificateBuilder::new()
.issuer_name(issuer_der)
.subject_name(subject_der)
.public_key_der(&spki_der)
.serial_number(Integer::from(1i64))
.not_valid_before(Time::UtcTime(UtcTime::new(2024, 1, 1, 0, 0, 0).unwrap()))
.not_valid_after(Time::UtcTime(UtcTime::new(2025, 1, 1, 0, 0, 0).unwrap()))
.sign(signer.as_ref())
.expect("certificate signing failed");
```
When you already hold an OpenSSL `PKey`, use `OpensslCertificateSigner` directly
(requires the `openssl` feature):
```rust,ignore
use synta_certificate::{CertificateBuilder, OpensslCertificateSigner};
let pkey: openssl::pkey::PKey<_> = /* existing OpenSSL private key */;
let signer = OpensslCertificateSigner::new(&pkey, "sha256");
let cert_der: Vec<u8> = CertificateBuilder::new()
/* … set fields … */
.sign(&signer)
.expect("certificate signing failed");
```
## Building a CSR
```rust,ignore
use synta_certificate::{CsrBuilder, PrivateKeyBuilder};
let key = PrivateKeyBuilder::rsa(3072).generate()?;
let spki = key.public_key_spki_der()?;
let signer = key.as_signer("sha256");
let csr_der: Vec<u8> = CsrBuilder::new()
.subject_name(subject_der)
.public_key_der(&spki)
.sign(signer.as_ref())
.expect("CSR signing failed");
```
## Building a PKCS#12 archive
```rust,ignore
use synta_certificate::{Pkcs12Builder, OpensslPkcs12Encryptor};
let pfx_der: Vec<u8> = Pkcs12Builder::new()
.certificate(&cert_der)
.private_key(&key_der)
.build(b"s3cr3t", &OpensslPkcs12Encryptor::new())
.expect("PKCS#12 build failed");
std::fs::write("keystore.p12", &pfx_der)?;
```
## Verifying a certificate chain
See [PKI: Verification](../pki/verification.md) for the full chain verification
API including trust store setup, policy configuration, and revocation checking.
## Next steps
- [PKI: Certificate](../pki/certificate.md) — full Certificate API reference
- [PKI: Keys](../pki/keys.md) — public key decoding and algorithm identification
- [PKI: Extensions](../pki/extensions.md) — extension access and encoding helpers
- [PKI: Verification](../pki/verification.md) — RFC 5280 path validation