static OcesCertificate SelectCertificateSubclass(String subjectSerialNumber, Ca signingCa, X509Certificate2 endUserCertificate) { var currentEnv = GetEnvironmentForRoot(signingCa); if (subjectSerialNumber.StartsWith("PID:") && MatchPocesPolicy(endUserCertificate, currentEnv)) { return(new PocesCertificate(endUserCertificate, signingCa)); } const int lengthOfCvrXxxxxxxx = 12; if (subjectSerialNumber.StartsWith("CVR:") && subjectSerialNumber.Substring(lengthOfCvrXxxxxxxx).StartsWith("-RID:") && MatchMocesPolicy(endUserCertificate, currentEnv)) { return(new MocesCertificate(endUserCertificate, signingCa)); } if (subjectSerialNumber.StartsWith("CVR:") && subjectSerialNumber.Substring(lengthOfCvrXxxxxxxx).StartsWith("-UID:") && MatchVocesPolicy(endUserCertificate, currentEnv)) { return(new VocesCertificate(endUserCertificate, signingCa)); } if (subjectSerialNumber.StartsWith("CVR:") && subjectSerialNumber.Substring(lengthOfCvrXxxxxxxx).StartsWith("-FID:") && MatchFocesPolicy(endUserCertificate, currentEnv)) { return(new FocesCertificate(endUserCertificate, signingCa)); } throw new NonOcesCertificateException("End user certificate is not POCES, MOCES, VOCES og FOCES"); }
private static OcesEnvironment GetEnvironmentForRoot(Ca ca) { if (!ca.IsRoot) { return(GetEnvironmentForRoot(ca.IssuingCa)); } return(RootCertificates.GetEnvironment(ca)); }
static bool CertificateIsValid(CertID id, OcspResp ocspResp, string serialNumber, Ca ca) { CheckOcspResp(ocspResp); BasicOcspResp response = GetResponseObject(ocspResp); CheckValidityOfResponse(id, response, ca); return SerialNumberInResponseIsNotRevoked(response, serialNumber); }
/// <summary> /// Constructs a CA with <code>certificate</code> as the certificate of this /// CA and <code>issuingCa</code> as the parent CA which has signed the /// certificate of this CA /// </summary> /// <param name="certificate">CA certificate</param> /// <param name="issuingCa">CA which has signed the certificate of this CA</param> public Ca(X509Certificate2 certificate, Ca issuingCa) { if (certificate == null) { throw new ArgumentException("Certificate cannot be null"); } Certificate = certificate; IssuingCa = issuingCa; }
/// <summary> /// Constructs a CA with <code>certificate</code> as the certificate of this /// CA and <code>issuingCa</code> as the parent CA which has signed the /// certificate of this CA /// </summary> /// <param name="certificate">CA certificate</param> /// <param name="issuingCa">CA which has signed the certificate of this CA</param> public Ca(X509Certificate2 certificate, Ca issuingCa) { if (certificate == null) { throw new ArgumentException("Certificate cannot be null"); } Certificate = certificate; IssuingCa = issuingCa; }
static Ca CreateCaChain(IList <X509Certificate2> certificates) { Ca parent = null; for (int i = certificates.Count - 1; i > 0; i--) { parent = new Ca(certificates[i], parent); } return(parent); }
public static bool VerifyTrust(X509Certificate2 certificate, Ca signingCa) { var basicConstraints = X509CertificatePropertyExtrator.GetBasicConstraints(certificate); if (Verify(certificate, GetPublicKey(signingCa.Certificate))) { if (VerifyChain(signingCa, 0)) { return VerifyRoot(signingCa); } } return false; }
public static bool VerifyTrust(X509Certificate2 certificate, Ca signingCa) { var basicConstraints = X509CertificatePropertyExtrator.GetBasicConstraints(certificate); if (Verify(certificate, GetPublicKey(signingCa.Certificate))) { if (VerifyChain(signingCa, 0)) { return(VerifyRoot(signingCa)); } } return(false); }
static bool VerifyRoot(Ca ca) { if (ca.IsRoot) { var certificates = Environments.TrustedCertificates; foreach (var certificate in certificates) { if (certificate.Equals(ca.Certificate)) { return(true); } } return(false); } return(VerifyRoot(ca.IssuingCa)); }
private static bool VerifyChain(Ca ca, int pathLength) { var basicConstraints = X509CertificatePropertyExtrator.GetBasicConstraints(ca.Certificate); //check that CA certificate is in fact a CA if (!basicConstraints.CertificateAuthority) { return(false); } //check that CA certificate must sign other certificates X509KeyUsageFlags flags = X509CertificatePropertyExtrator.GetKeyUsage(ca.Certificate).KeyUsages; if ((flags & (X509KeyUsageFlags.KeyCertSign)) != X509KeyUsageFlags.KeyCertSign) { return(false); } // Check path length if (basicConstraints.HasPathLengthConstraint && basicConstraints.PathLengthConstraint < pathLength) { return(false); } if (IsSelfSigned(ca) && !ca.IsRoot) { return(false); } if (ca.IsRoot) { return(true); } if (ca.IssuingCa == null) { return(false); } Ca signingCa = ca.IssuingCa; if (X509CertificatePropertyExtrator.GetBasicConstraints(signingCa.Certificate).PathLengthConstraint >= 0) { if (Verify(ca.Certificate, GetPublicKey(signingCa.Certificate))) { return(VerifyChain(ca.IssuingCa, ++pathLength)); } } return(false); }
/// <summary> /// Generates an <code>OcesCertificate</code>. The returned <code>OcesCertificate</code> is the end user certificate, which has a parent relation /// to the certificate of its issuing CA which again can have a parent relation to the certificate of the root CA. /// The root CA has no parent relation. /// /// The factory verifies that each certificate in the certificate chain has been signed by its issuing CA. /// </summary> /// <param name="certificates">List of certificates to create OcesCertificate chain from.</param> /// <returns><code>OcesCertificate</code> with parent relation to (chain of) issuing CAs. Depending on the Subject DN in the /// certificate a <code>PocesCertificate</code>, <code>MocesCertificate</code>, <code>VocesCertificate</code>, or <code>FocesCertificate</code> will be created.</returns> /// <exception cref="org.openoces.ooapi.exceptions.TrustCouldNotBeVerifiedException">when a OcesCertificate in the chain cannot be trusted, i.e. has not been signed by its issuing CA.</exception> public OcesCertificate Generate(List <X509Certificate2> certificates) { certificates = SortCertificatesIssuerLast(certificates); AddIssuerCertificateIfNeeded(certificates); ValidateExactlyOneChainInList(certificates); AppendRootIfMissing(certificates); X509Certificate2 endUserCertificate = certificates[0]; Ca signingCa = CreateCaChain(certificates); string subjectSerialNumber = ExtractSubjectSerialNumber(endUserCertificate); OcesCertificate certificate = SelectCertificateSubclass(subjectSerialNumber, signingCa, endUserCertificate); if (ChainVerifier.VerifyTrust(certificate)) { return(certificate); } throw new TrustCouldNotBeVerifiedException(certificate, Environments.TrustedEnvironments); }
/// <summary> /// Gets <code>Environment</code> for given <code>CA</code> /// </summary> public static OcesEnvironment GetEnvironment(Ca ca) { if (ca == null) { throw new ArgumentException("Ca is null"); } if (!ca.IsRoot) { return GetEnvironment(ca.IssuingCa); } foreach (var e in TheRootCertificates) { if (e.Value.Equals(ca.Certificate)) { return e.Key; } } throw new ArgumentException(ca + " is not a known root certificate"); }
internal bool IsRevoked(Ca ca) { if (ca.IsRoot) { throw new InvalidOperationException("Cannot check revocation for root CA"); } try { VerifyCrl(ca.IssuingCa.Certificate); } catch (SignatureException e) { throw new InvalidSignatureException("CRL Issued by" + _crl.IssuerDN + " does not have valid signature by ca's issuer certificate " + ca.IssuingCa.Certificate.SubjectName.Name, e); } return IsRevoked(ca.Certificate); }
/// <summary> /// Creates a OcesCertificate. /// </summary> /// <param name="certificate"><code>X509Certificate</code> to encapsulate</param> /// <param name="issuingCa">parent relation to its issuing CA</param> protected OcesCertificate(X509Certificate2 certificate, Ca issuingCa) { Certificate = certificate; IssuingCa = issuingCa; SubjectSerialNumber = ExtractSubjectSerialNumber(certificate); }
private static bool VerifyChain(Ca ca, int pathLength) { var basicConstraints = X509CertificatePropertyExtrator.GetBasicConstraints(ca.Certificate); //check that CA certificate is in fact a CA if (!basicConstraints.CertificateAuthority) { return false; } //check that CA certificate must sign other certificates X509KeyUsageFlags flags = X509CertificatePropertyExtrator.GetKeyUsage(ca.Certificate).KeyUsages; if((flags & (X509KeyUsageFlags.KeyCertSign))!=X509KeyUsageFlags.KeyCertSign) { return false; } // Check path length if (basicConstraints.HasPathLengthConstraint && basicConstraints.PathLengthConstraint < pathLength) { return false; } if (IsSelfSigned(ca) && !ca.IsRoot) { return false; } if (ca.IsRoot) { return true; } if (ca.IssuingCa == null) { return false; } Ca signingCa = ca.IssuingCa; if (X509CertificatePropertyExtrator.GetBasicConstraints(signingCa.Certificate).PathLengthConstraint >= 0) { if (Verify(ca.Certificate, GetPublicKey(signingCa.Certificate))) { return VerifyChain(ca.IssuingCa, ++pathLength); } } return false; }
Crl DownloadCrl(Ca ca) { string crlDistributionPoint = CrlDistributionPointsExtractor.ExtractCrlDistributionPoints(ca.Certificate).CrlDistributionPoint; return DownloadCrl(crlDistributionPoint); }
static OcesCertificate SelectCertificateSubclass(String subjectSerialNumber, Ca signingCa, X509Certificate2 endUserCertificate) { var currentEnv = GetEnvironmentForRoot(signingCa); if (subjectSerialNumber.StartsWith("PID:") && MatchPocesPolicy(endUserCertificate, currentEnv)) { return new PocesCertificate(endUserCertificate, signingCa); } const int lengthOfCvrXxxxxxxx = 12; if (subjectSerialNumber.StartsWith("CVR:") && subjectSerialNumber.Substring(lengthOfCvrXxxxxxxx).StartsWith("-RID:") && MatchMocesPolicy(endUserCertificate, currentEnv)) { return new MocesCertificate(endUserCertificate, signingCa); } if (subjectSerialNumber.StartsWith("CVR:") && subjectSerialNumber.Substring(lengthOfCvrXxxxxxxx).StartsWith("-UID:") && MatchVocesPolicy(endUserCertificate, currentEnv)) { return new VocesCertificate(endUserCertificate, signingCa); } if (subjectSerialNumber.StartsWith("CVR:") && subjectSerialNumber.Substring(lengthOfCvrXxxxxxxx).StartsWith("-FID:") && MatchFocesPolicy(endUserCertificate, currentEnv)) { return new FocesCertificate(endUserCertificate, signingCa); } throw new NonOcesCertificateException("End user certificate is not POCES, MOCES, VOCES og FOCES"); }
Crl DownloadCrl(Ca ca, OcesEnvironment environment) { string crlDistributionPoint = CrlDistributionPointsExtractor.ExtractCrlDistributionPoints(ca.Certificate).PartitionedCrlDistributionPoint; return _crlDownloader.Download(environment, crlDistributionPoint); }
static Ca CreateCaChain(IList<X509Certificate2> certificates) { Ca parent = null; for (int i = certificates.Count - 1; i > 0; i--) { parent = new Ca(certificates[i], parent); } return parent; }
private static X509Certificate2[] CreateOcspCertificateChain(Ca ca) { var chain = new List<X509Certificate2> (); while (ca != null) { chain.Add(ca.Certificate); ca = ca.IssuingCa; } return chain.ToArray(); }
static void CheckValidityOfResponse(CertID id, BasicOcspResp responseObject, Ca ca) { var inputStream = new MemoryStream(responseObject.GetEncoded()); var asn1Sequence = (Asn1Sequence)new Asn1InputStream(inputStream).ReadObject(); var response = BasicOcspResponse.GetInstance(asn1Sequence); var ocspChain = CreateOcspCertificateChain(ca); if(ocspChain.Length == 0) { throw new OcspException("OCSP certificate chain is invalid"); } var ocesOcspCertificate = OcesCertificateFactory.Instance.Generate(CompleteOcspChain(response, ocspChain)); CheckBasicOcspResp(id, responseObject, ocesOcspCertificate, ca); var signingCertificate = new X509CertificateParser().ReadCertificate(response.Certs[0].GetEncoded()); var issuingCertificate = new X509CertificateParser().ReadCertificate(ocspChain[0].GetRawCertData()); signingCertificate.Verify(issuingCertificate.GetPublicKey()); if (!responseObject.Verify(signingCertificate.GetPublicKey())) { throw new OcspException("Signature is invalid"); } }
private static bool IsSelfSigned(Ca ca) { return Verify(ca.Certificate, GetPublicKey(ca.Certificate)); }
static bool VerifyRoot(Ca ca) { if (ca.IsRoot) { var certificates = Environments.TrustedCertificates; foreach (var certificate in certificates) { if (certificate.Equals(ca.Certificate)) { return true; } } return false; } return VerifyRoot(ca.IssuingCa); }
private static OcesEnvironment GetEnvironmentForRoot(Ca ca) { if (!ca.IsRoot) { return GetEnvironmentForRoot(ca.IssuingCa); } return RootCertificates.GetEnvironment(ca); }
/// <summary> /// Creates a OcesCertificate. /// </summary> /// <param name="certificate"><code>X509Certificate</code> to encapsulate</param> /// <param name="issuingCa">parent relation to its issuing CA</param> protected OcesCertificate(X509Certificate2 certificate, Ca issuingCa) { Certificate = certificate; IssuingCa = issuingCa; SubjectSerialNumber = ExtractSubjectSerialNumber(certificate); }
/// <summary> /// Contructs a VOCES certificate with the given <code>CA</code> as parent /// </summary> /// <param name="certificate">certificate</param> /// <param name="parent">parent signing CA</param> public VocesCertificate(X509Certificate2 certificate, Ca parent) : base(certificate, parent) { }
public bool IsRevoked(Ca ca) { if (ca.IsRoot) { return false; } OcesEnvironment environment = RootCertificates.GetEnvironment(ca.IssuingCa); return DownloadCrl(ca, environment).IsRevoked(ca) || IsRevoked(ca.IssuingCa); }
private static void CheckBasicOcspResp(CertID id, BasicOcspResp basicResp, OcesCertificate ocspCertificate, Ca ca) { DateTime nowInGmt = DateTime.Now.ToUniversalTime(); /* check condition: The certificate identified in a received response corresponds to that which was identified in the corresponding request; */ SingleResp[] responses = basicResp.Responses; if (responses.Length != 1) { throw new OcspException("unexpected number of responses received"); } if (!id.SerialNumber.Value.Equals(responses[0].GetCertID().SerialNumber)) { throw new OcspException("Serial number mismatch problem"); } /* check condition The signature on the response is valid; */ try { ChainVerifier.VerifyTrust(ocspCertificate.ExportCertificate(), ca); } catch(ChainVerificationException e) { throw new OcspException("OCSP response certificate chain is invalid", e); } /* check the signature on the ocsp response */ var ocspBcCertificate = new X509CertificateParser().ReadCertificate(ocspCertificate.ExportCertificate().RawData); if (!basicResp.Verify(ocspBcCertificate.GetPublicKey())) { throw new OcspException("signature validation failed for ocsp response"); } if (!CanSignOcspResponses(ocspBcCertificate)) { throw new OcspException("ocsp signing certificate has not been cleared for ocsp response signing"); } /* check expiry of the signing certificate */ if (ocspCertificate.ValidityStatus() != CertificateStatus.Valid) { throw new OcspException("OCSP certificate expired or not yet valid"); } /* check condition The time at which the status being indicated is known to be correct (thisUpdate) is sufficiently recent. */ SingleResp response = responses[0]; var diff = response.ThisUpdate - nowInGmt; if (diff > new TimeSpan(0, 1, 0)) { throw new OcspException("OCSP response signature is from the future. Timestamp of thisUpdate field: " + response.ThisUpdate); } if (response.NextUpdate != null && response.NextUpdate.Value < nowInGmt) { throw new OcspException("OCSP response is no longer valid"); } }
public bool IsRevoked(Ca ca) { if (ca.IsRoot) { return false; } return DownloadCrl(ca).IsRevoked(ca) || IsRevoked(ca.IssuingCa); }
/// <summary> /// Contructs a POCES certificate with the given <code>CA</code> as parent /// </summary> /// <param name="certificate">certificate</param> /// <param name="parent">parent signing CA</param> public PocesCertificate(X509Certificate2 certificate, Ca parent) : base(certificate, parent) { }
private static bool IsSelfSigned(Ca ca) { return(Verify(ca.Certificate, GetPublicKey(ca.Certificate))); }