# 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
| `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 |