/// <summary> /// Gets the <see cref="OcspResp"/> for the <see cref="OcspReq"/> /// </summary> /// <param name="ocspRequest"></param> /// <param name="issuerCertificate"></param> /// <returns></returns> private async Task <OcspResp> GetOcspDefinitiveResponse(OcspReq ocspRequest, X509Certificate issuerCertificate) { var basicResponseGenerator = new BasicOcspRespGenerator( new RespID( await OcspResponderRepository.GetResponderPublicKey(issuerCertificate))); var extensionsGenerator = new X509ExtensionsGenerator(); var nextUpdate = await OcspResponderRepository.GetNextUpdate(); foreach (var request in ocspRequest.GetRequestList()) { var certificateId = request.GetCertID(); var serialNumber = certificateId.SerialNumber; CertificateStatus certificateStatus; CaCompromisedStatus caCompromisedStatus = await OcspResponderRepository.IsCaCompromised(issuerCertificate); if (caCompromisedStatus.IsCompromised) { // See section 2.7 of RFC 6960 certificateStatus = new RevokedStatus(caCompromisedStatus.CompromisedDate.Value.UtcDateTime, (int)RevocationReason.CACompromise); } else { // Se section 2.2 of RFC 6960 if (await OcspResponderRepository.SerialExists(serialNumber, issuerCertificate)) { var status = await OcspResponderRepository.SerialIsRevoked(serialNumber, issuerCertificate); certificateStatus = status.IsRevoked ? new RevokedStatus(status.RevokedInfo.Date.UtcDateTime, (int)status.RevokedInfo.Reason) : CertificateStatus.Good; } else { certificateStatus = new RevokedStatus(new DateTime(1970, 1, 1), CrlReason.CertificateHold); extensionsGenerator.AddExtension(OcspObjectIdentifierExtensions.PkixOcspExtendedRevoke, false, DerNull.Instance.GetDerEncoded()); } } basicResponseGenerator.AddResponse(certificateId, certificateStatus, DateTimeOffset.UtcNow.DateTime, nextUpdate.UtcDateTime, null); } SetNonceExtension(ocspRequest, extensionsGenerator); basicResponseGenerator.SetResponseExtensions(extensionsGenerator.Generate()); // Algorithm that all clients shall accept as defined in section 4.3 of RFC 6960 const string signatureAlgorithm = "sha256WithRSAEncryption"; var basicOcspResponse = basicResponseGenerator.Generate( signatureAlgorithm, await OcspResponderRepository.GetResponderPrivateKey(issuerCertificate), await OcspResponderRepository.GetChain(issuerCertificate), nextUpdate.UtcDateTime); var ocspResponse = OcspResponseGenerator.Generate(OcspRespStatus.Successful, basicOcspResponse); return(ocspResponse); }
//requires the extended revocation extension to be included in the basic response public void AddExtendedRevocationResponse(CertificateID cert_id) { var status = new RevokedStatus(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), (int)CrlReason.certificateHold); _builder.AddResponse(cert_id, status, DateTime.UtcNow.AddMinutes(_nextupdate), null); //now add the extended revocation extension var extended_revoke_oid = new DerObjectIdentifier("1.3.6.1.5.5.7.48.1.9"); //don't crash if extension was already added try{ _extensions_generator.AddExtension(extended_revoke_oid, false, DerNull.Instance.GetEncoded()); }catch (System.ArgumentException) {} }
public void AddRevokedResponse(CertificateID cert_id, X509CrlEntry crl_entry) { int reason; var crl_reason_oid = X509Extensions.ReasonCode; var ext_reason = crl_entry.GetExtensionValue(crl_reason_oid); if (ext_reason != null) { var asn1_reason = new DerEnumerated(ext_reason.GetEncoded()); reason = asn1_reason.Value.IntValue; } else { reason = (int)CrlReason.unspecified; } CertificateStatus status = new RevokedStatus(crl_entry.RevocationDate, reason); _builder.AddResponse(cert_id, status, DateTime.UtcNow.AddMinutes(_nextupdate), null); }
public void AddCaCompromisedResponse(CertificateID cert_id) { var status = new RevokedStatus(DateTime.UtcNow, (int)CrlReason.caCompromise); _builder.AddResponse(cert_id, status); }
public override void handlePOSTRequest(HttpProcessor p, MemoryStream ms) { try { byte[] ocspdata = ms.ToArray(); OcspReq req = new OcspReq(ocspdata); GeneralName name = req.RequestorName; if (validator != null) { string stat = "GOOD"; foreach (CertificateID id in req.GetIDs()) { Stopwatch st = new Stopwatch(); st.Start(); OCSPCache cac = GetCache(id.SerialNumber.LongValue); if (cac != null) { Console.Write("[CACHED] "); string header = GetRFC822Date(cac.CacheTime); byte[] responseBytes = cac.data; p.outputStream.WriteLine("HTTP/1.1 200 OK"); p.outputStream.WriteLine("content-transfer-encoding: binary"); p.outputStream.WriteLine("Last-Modified: " + header); p.outputStream.WriteLine("Content-Type: application/ocsp-response"); p.outputStream.WriteLine("Connection: keep-alive"); p.outputStream.WriteLine("Accept-Ranges: bytes"); p.outputStream.WriteLine("Server: AS-OCSP-1.0"); p.outputStream.WriteLine("Content-Length: " + responseBytes.Length.ToString()); p.outputStream.WriteLine(""); p.outputStream.WriteContent(responseBytes); } else { // validate OCSPRespGenerator gen = new OCSPRespGenerator(); BasicOcspRespGenerator resp = new BasicOcspRespGenerator(validator.CACert.GetPublicKey()); DerGeneralizedTime dt = new DerGeneralizedTime(DateTime.Parse("03/09/2014 14:00:00")); CrlReason reason = new CrlReason(CrlReason.CACompromise); if (validator.IsRevoked(id, ref dt, ref reason)) { RevokedInfo rinfo = new RevokedInfo(dt, reason); RevokedStatus rstatus = new RevokedStatus(rinfo); resp.AddResponse(id, rstatus); stat = "REVOKED"; } else { resp.AddResponse(id, CertificateStatus.Good); } BasicOcspResp response = resp.Generate("SHA1withRSA", validator.CAKey, new X509Certificate[] { validator.CACert }, DateTime.Now); OcspResp or = gen.Generate(OCSPRespGenerator.Successful, response); string header = GetRFC822Date(DateTime.Now); byte[] responseBytes = or.GetEncoded(); AddCache(responseBytes, id.SerialNumber.LongValue); p.outputStream.WriteLine("HTTP/1.1 200 OK"); p.outputStream.WriteLine("content-transfer-encoding: binary"); p.outputStream.WriteLine("Last-Modified: " + header); p.outputStream.WriteLine("Content-Type: application/ocsp-response"); p.outputStream.WriteLine("Connection: keep-alive"); p.outputStream.WriteLine("Accept-Ranges: bytes"); p.outputStream.WriteLine("Server: AS-OCSP-1.0"); p.outputStream.WriteLine("Content-Length: " + responseBytes.Length.ToString()); p.outputStream.WriteLine(""); p.outputStream.WriteContent(responseBytes); } Console.Write(id.SerialNumber + " PROCESSED IN " + st.Elapsed + " STATUS " + stat); Console.WriteLine(""); } } else { p.writeFailure(); } } catch (Exception ex) { Console.WriteLine("OCSP Server Error : " + ex.Message); } }