Category: Certificate Signing Requests (CSR)
Complexity: * (Medium-High)
Prerequisites: CSR file available, CA access
Estimated Time: 10-15 minutes
</WRAP>
—-
===== 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 =====
<mermaid>
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
</mermaid>
—-
===== Code Example (C#) =====
<code csharp>
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“);
</code>
—-
===== Policy Validation =====
<code csharp>
public class CsrPolicyValidator
{
public PolicyResult ValidateCsrPolicy(CertificateRequest csr)
{
var errors = new List<string>();
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
};
}
}
</code>
—-
===== Automated CSR Processing =====
For automated environments (ACME, EST):
<code csharp>
public async Task<Certificate> 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;
}
</code>
—-
===== 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 | 3.1 Server Certificate | Issue certificate |
| Prerequisite | 2.1 Server CSR | Create CSR |
| Related | 5.4 Policy Validation | Extended policy checking |
—-
« <- 2.3 Multi-SAN CSR | ^ CSR Overview | 3. Issue Certificates -> »
—- Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional