====== 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//