# CertificationRequest (CSR)
`CertificationRequest` represents an RFC 2986 PKCS#10 Certificate Signing Request.
## Construction
```python
CertificationRequest.from_der(data: bytes) -> CertificationRequest
CertificationRequest.from_pem(data: bytes) -> CertificationRequest | list[CertificationRequest]
CertificationRequest.to_pem(csr_or_list) -> bytes
```
## Properties
| `version` | `int` | CSR version (always `0` = v1 per RFC 2986) |
| `subject` | `str` | RFC 4514 DN string |
| `subject_raw_der` | `bytes` | Raw DER of subject Name SEQUENCE |
| `signature_algorithm` | `str` | Algorithm name or dotted OID |
| `signature_algorithm_oid` | `ObjectIdentifier` | |
| `signature` | `bytes` | Raw signature bytes |
| `public_key_algorithm` | `str` | Algorithm name or dotted OID |
| `public_key_algorithm_oid` | `ObjectIdentifier` | |
| `public_key` | `bytes` | Raw subject public key bytes |
## Methods
| `to_der()` | `()` | `bytes` | Original DER bytes |
| `get_extension_value_der` | `(oid: str \| ObjectIdentifier)` | `bytes \| None` | Return the extnValue bytes of the named extension from the CSR's `extensionRequest` attribute, or `None` if absent. |
| `subject_alt_names()` | `()` | `list[tuple[int, bytes]]` | Parse the SAN extension from the CSR's `extensionRequest` attribute. Returns `(tag_number, content_bytes)` pairs — the same format as `synta.parse_general_names()`. Returns an empty list if no SAN is present. |
| `verify_self_signature()` | `()` | `None` | Verify the PKCS#10 self-signature. Raises `ValueError` if the signature is invalid or the algorithm is unsupported. |
## Full class stub
```python
class CertificationRequest:
@staticmethod
def from_der(data: bytes) -> CertificationRequest: ...
@staticmethod
def from_pem(data: bytes) -> CertificationRequest | list[CertificationRequest]: ...
@staticmethod
def to_pem(csr_or_list) -> bytes: ...
version: int
subject: str
subject_raw_der: bytes
signature_algorithm: str
signature_algorithm_oid: ObjectIdentifier
signature: bytes
public_key_algorithm: str
public_key_algorithm_oid: ObjectIdentifier
public_key: bytes
def to_der(self) -> bytes: ...
def get_extension_value_der(self, oid: str) -> bytes | None: ...
def subject_alt_names(self) -> list[tuple[int, bytes]]: ...
def verify_self_signature(self) -> None: ...
```
## Usage
```python
import synta
# Parse from DER
with open("request.csr", "rb") as f:
csr = synta.CertificationRequest.from_der(f.read())
# Parse from PEM
pem_data = open("request.pem", "rb").read()
csr = synta.CertificationRequest.from_pem(pem_data)
# Access fields
print(csr.subject)
print(csr.public_key_algorithm)
print(csr.public_key_algorithm_oid)
# Verify the self-signature
try:
csr.verify_self_signature()
print("CSR self-signature is valid")
except ValueError as e:
print(f"Invalid CSR: {e}")
# Retrieve the extensionRequest attribute (if present)
san_der = csr.get_extension_value_der("2.5.29.17") # SubjectAltName
if san_der:
# san_der is the extnValue content bytes — pass to a Decoder
dec = synta.Decoder(san_der, synta.Encoding.DER)
san_seq = dec.decode_sequence()
while not san_seq.is_empty():
tag_num, tag_class, _ = san_seq.peek_tag()
child = san_seq.decode_implicit_tag(tag_num, "Context")
print(f"SAN tag {tag_num}: {child.remaining_bytes()}")
```
See also [Certificate](certificate.md) for the issued certificate type and
[CRL](crl.md) for certificate revocation lists.