====== Scenario 2.4: Process CSR ======
**Category:** [[.:start|Certificate Signing Requests (CSR)]] \\
**Complexity:** *** (Medium-High) \\
**Prerequisites:** CSR file available, CA access \\
**Estimated Time:** 10-15 minutes
----
===== Description =====
This scenario describes the **processing of a submitted CSR** by a Certificate Authority (CA). This includes validation, policy checking, and certificate issuance.
**Steps:**
- Load and parse CSR
- Verify signature (proof-of-possession)
- Check policy conformity
- Issue certificate
----
===== Workflow =====
flowchart TB
LOAD[Load CSR] --> PARSE[Parse CSR]
PARSE --> VERIFY[Verify signature]
VERIFY --> POLICY{Check policy}
POLICY -->|OK| ISSUE[Issue certificate]
POLICY -->|Error| REJECT[Reject CSR]
ISSUE --> RETURN[Return certificate]
style VERIFY fill:#e3f2fd
style ISSUE fill:#e8f5e9
style REJECT fill:#ffcdd2
----
===== Code Example (C#) =====
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using var ctx = PqCryptoContext.Initialize();
// 1. Load CSR
var csrPem = File.ReadAllText("server.csr.pem");
var csr = ctx.LoadCertificateRequest(csrPem);
// 2. Display CSR information
Console.WriteLine("=== CSR Analysis ===");
Console.WriteLine($"Subject: {csr.Subject}");
Console.WriteLine($"Public Key Algorithm: {csr.PublicKeyAlgorithm}");
Console.WriteLine($"Public Key Size: {csr.PublicKeySize} bytes");
Console.WriteLine($"Signature Algorithm: {csr.SignatureAlgorithm}");
Console.WriteLine("\nSubject Alternative Names:");
foreach (var san in csr.SubjectAlternativeNames)
{
Console.WriteLine($" - {san}");
}
Console.WriteLine("\nRequested Extensions:");
foreach (var ext in csr.RequestedExtensions)
{
Console.WriteLine($" - {ext.Oid}: {ext.FriendlyName}");
}
// 3. Verify signature (proof-of-possession)
bool signatureValid = csr.VerifySignature();
Console.WriteLine($"\nSignature valid: {signatureValid}");
if (!signatureValid)
{
throw new CryptographicException("CSR signature invalid - aborting");
}
// 4. Policy check
var policyResult = ValidateCsrPolicy(csr);
if (!policyResult.IsValid)
{
Console.WriteLine($"Policy error: {policyResult.ErrorMessage}");
return;
}
// 5. Issue certificate (see Scenario 3.1)
Console.WriteLine("\n+ CSR validated - ready for certificate issuance");
----
===== Policy Validation =====
public class CsrPolicyValidator
{
public PolicyResult ValidateCsrPolicy(CertificateRequest csr)
{
var errors = new List();
// 1. Check algorithm
var allowedAlgorithms = new[] { "ML-DSA-44", "ML-DSA-65", "ML-DSA-87" };
if (!allowedAlgorithms.Contains(csr.PublicKeyAlgorithm))
{
errors.Add($"Algorithm '{csr.PublicKeyAlgorithm}' not allowed");
}
// 2. Check key size
if (csr.PublicKeyAlgorithm == "ML-DSA-44")
{
errors.Add("ML-DSA-44 has too low security for production environments");
}
// 3. Check subject
if (string.IsNullOrEmpty(csr.Subject.CommonName))
{
errors.Add("Common Name (CN) is required");
}
// 4. Check SANs
if (csr.SubjectAlternativeNames.Count == 0)
{
errors.Add("At least one SAN is required");
}
// 5. Check forbidden domains
var forbiddenDomains = new[] { "localhost", "*.local", "*.internal" };
foreach (var san in csr.SubjectAlternativeNames)
{
if (forbiddenDomains.Any(f => san.Contains(f)))
{
errors.Add($"Forbidden domain in SAN: {san}");
}
}
// 6. Wildcard rules
var wildcardCount = csr.SubjectAlternativeNames.Count(s => s.StartsWith("*."));
if (wildcardCount > 1)
{
errors.Add("Maximum one wildcard SAN allowed");
}
return new PolicyResult
{
IsValid = errors.Count == 0,
Errors = errors
};
}
}
----
===== Automated CSR Processing =====
For automated environments (ACME, EST):
public async Task ProcessCsrAutomatedAsync(
string csrPem,
string requesterIdentity,
CancellationToken ct)
{
var csr = ctx.LoadCertificateRequest(csrPem);
// 1. Verify signature
if (!csr.VerifySignature())
throw new SecurityException("Invalid CSR signature");
// 2. Check requester authorization
if (!await IsAuthorizedForDomains(requesterIdentity, csr.SubjectAlternativeNames, ct))
throw new UnauthorizedAccessException("Not authorized for these domains");
// 3. Rate limiting
await CheckRateLimitAsync(requesterIdentity, ct);
// 4. Issue certificate
var cert = ctx.IssueCertificate(
csr,
issuerCert: intermediateCa,
issuerKey: intermediateCaKey,
validDays: 90 // Short validity for automation
);
// 5. Audit log
await LogCertificateIssuance(cert, requesterIdentity, ct);
return cert;
}
----
===== CSR Formats =====
^ Format ^ Detection ^ Conversion ^
| PEM | ''-----BEGIN CERTIFICATE REQUEST-----'' | Directly usable |
| DER | Binary, no header | ''ctx.LoadCertificateRequestDer(bytes)'' |
| PKCS#10 | Synonym for CSR | - |
----
===== Related Scenarios =====
^ Relationship ^ Scenario ^ Description ^
| **Next Step** | [[en:int:pqcrypt:szenarien:zertifikate:server_cert|3.1 Server Certificate]] | Issue certificate |
| **Prerequisite** | [[.:csr_server|2.1 Server CSR]] | Create CSR |
| **Related** | [[en:int:pqcrypt:szenarien:validierung:policy_validation|5.4 Policy Validation]] | Extended policy checking |
----
<< [[.:csr_multi_san|<- 2.3 Multi-SAN CSR]] | [[.:start|^ CSR Overview]] | [[en:int:pqcrypt:szenarien:zertifikate:start|3. Issue Certificates ->]] >>
{{tag>scenario csr processing validation policy ca}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//