1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package dk.sosi.seal.pki;
30
31 import java.security.cert.X509Certificate;
32
33
34
35
36
37
38
39
40
41 public abstract class AbstractOCESCertificationAuthority implements CertificationAuthority {
42
43 private final CertificateStatusChecker certificateStatusChecker;
44 private final IntermediateCertificateCache intermediateCertificateCache;
45 private final FederationCertificateResolver federationCertificateResolver;
46 private final AuditEventHandler eventHandler;
47
48 protected AbstractOCESCertificationAuthority(SOSIConfiguration configuration,
49 CertificateStatusChecker certificateStatusChecker, IntermediateCertificateCache intermediateCertificateCache, FederationCertificateResolver federationCertificateResolver) {
50 configuration.verify();
51 if (certificateStatusChecker == null) throw new IllegalArgumentException("'certificateStatusChecker' cannot be null");
52 if (intermediateCertificateCache == null) throw new IllegalArgumentException("'intermediateCertificateCache' cannot be null");
53
54 this.eventHandler = configuration.getAuditEventHandler();
55
56 this.certificateStatusChecker = certificateStatusChecker;
57 this.intermediateCertificateCache = intermediateCertificateCache;
58 this.federationCertificateResolver = federationCertificateResolver;
59 }
60
61 public final boolean isValid(X509Certificate certificate) throws PKIException {
62 return getCertificateStatus(certificate).isValid();
63 }
64
65 public CertificateStatus getCertificateStatus(final X509Certificate cert) throws PKIException {
66 CertificateStatus certificateStatus;
67 if (checkDates(cert)) {
68 if (!(OCESUtil.isOCES1Certificate(cert) && OCESUtil.isIssuerOf(cert, getOCES1RootCertificate()) || OCESUtil.isOCES2Certificate(cert) && OCESUtil.isIssuerOf(cert, getAndValidateIntermediateCertificate(cert)))) {
69 throw new PKIException("The supplied certificate is not a " + getCertificationAuthorityName() + " certificate");
70 }
71 certificateStatus = checkRevocation(cert);
72 } else {
73 certificateStatus = new CertificateStatus(false, null);
74 }
75 auditLogCertificationStatus(certificateStatus, cert);
76 return certificateStatus;
77 }
78
79 private void auditLogCertificationStatus(CertificateStatus certificateStatus, Object certificate) {
80 if (certificateStatus.isValid()) {
81 eventHandler.onInformationalAuditingEvent(AuditEventHandler.EVENT_TYPE_INFO_CERTIFICATE_VALIDATED, new Object[]{certificate});
82 } else {
83 eventHandler.onErrorAuditingEvent(AuditEventHandler.EVENT_TYPE_ERROR_VALIDATING_CERTIFICATE, new Object[]{certificate});
84 }
85 }
86
87 protected abstract X509Certificate getOCES1RootCertificate();
88
89
90
91
92 protected abstract X509Certificate[] getOCES2RootCertificates();
93
94 protected abstract String getCertificationAuthorityName();
95
96 private boolean checkDates(X509Certificate certificate) {
97 if (certificate.getNotAfter().getTime() < System.currentTimeMillis()) {
98 return false;
99 } else if (certificate.getNotBefore().getTime() > System.currentTimeMillis()) {
100 return false;
101 }
102 return true;
103 }
104
105 private X509Certificate getAndValidateIntermediateCertificate(X509Certificate certificate) throws PKIException {
106 X509Certificate intermediateCertificate = intermediateCertificateCache.getCertificate(OCESUtil.retrieveIntermediateCertificateURI(certificate));
107
108 if (!checkDates(intermediateCertificate)) {
109 throw new PKIException("Intermediate certificate not valid in time");
110 }
111 boolean isIssuedByRoot = false;
112 for (X509Certificate rootCertificate : getOCES2RootCertificates()) {
113 isIssuedByRoot = OCESUtil.isIssuerOf(intermediateCertificate, rootCertificate);
114 if (isIssuedByRoot) break;
115 }
116 if (!isIssuedByRoot) throw new PKIException("Intermediate certificate not issued by " + getCertificationAuthorityName() + " root certificate");
117
118
119
120 if (!checkRevocation(intermediateCertificate).isValid()) {
121 throw new PKIException("Intermediate certificate is revoked");
122 }
123 return intermediateCertificate;
124 }
125
126 private CertificateStatus checkRevocation(X509Certificate certificate) {
127 try {
128 return certificateStatusChecker.getRevocationStatus(certificate);
129 } catch (PKIException e) {
130 eventHandler.onWarningAuditingEvent(e.getMessage(), null);
131 throw e;
132 }
133 }
134
135 public X509Certificate getFederationCertificate(FederationCertificateReference reference) {
136 return federationCertificateResolver.getFederationCertificate(reference);
137 }
138
139 }