001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.util;
028
029
030
031 import java.security.cert.CertificateException;
032 import java.security.cert.CertificateExpiredException;
033 import java.security.cert.CertificateNotYetValidException;
034 import java.security.cert.X509Certificate;
035 import java.util.Date;
036 import javax.net.ssl.X509TrustManager;
037
038
039
040 import static org.opends.server.loggers.ErrorLogger.*;
041 import static org.opends.messages.UtilityMessages.*;
042 import org.opends.messages.Message;
043
044
045 /**
046 * This class implements an X.509 trust manager that will be used to wrap an
047 * existing trust manager and makes it possible to reject a presented
048 * certificate if that certificate is outside the validity window.
049 */
050 @org.opends.server.types.PublicAPI(
051 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
052 mayInstantiate=true,
053 mayExtend=false,
054 mayInvoke=true)
055 public final class ExpirationCheckTrustManager
056 implements X509TrustManager
057 {
058 // The trust manager that is wrapped by this trust manager.
059 private X509TrustManager trustManager;
060
061
062
063 /**
064 * Creates a new instance of this trust manager that will wrap the provided
065 * trust manager.
066 *
067 * @param trustManager The trust manager to be wrapped by this trust
068 * manager.
069 */
070 public ExpirationCheckTrustManager(X509TrustManager trustManager)
071 {
072 this.trustManager = trustManager;
073 }
074
075
076
077 /**
078 * Determines whether to trust the peer based on the provided certificate
079 * chain. In this case, the peer will only be trusted if all certificates in
080 * the chain are within the validity window and the parent trust manager also
081 * accepts the certificate.
082 *
083 * @param chain The peer certificate chain.
084 * @param authType The authentication type based on the client certificate.
085 *
086 * @throws CertificateException If the client certificate chain is not
087 * trusted.
088 */
089 public void checkClientTrusted(X509Certificate[] chain, String authType)
090 throws CertificateException
091 {
092 Date currentDate = new Date();
093 for (X509Certificate c : chain)
094 {
095 try
096 {
097 c.checkValidity(currentDate);
098 }
099 catch (CertificateExpiredException cee)
100 {
101 Message message = ERR_EXPCHECK_TRUSTMGR_CLIENT_CERT_EXPIRED.get(
102 c.getSubjectDN().getName(), String.valueOf(c.getNotAfter()));
103 logError(message);
104
105 throw cee;
106 }
107 catch (CertificateNotYetValidException cnyve)
108 {
109 Message message = ERR_EXPCHECK_TRUSTMGR_CLIENT_CERT_NOT_YET_VALID.get(
110 c.getSubjectDN().getName(), String.valueOf(c.getNotBefore()));
111 logError(message);
112
113 throw cnyve;
114 }
115 }
116
117 trustManager.checkClientTrusted(chain, authType);
118 }
119
120
121
122 /**
123 * Determines whether to trust the peer based on the provided certificate
124 * chain. In this case, the peer will only be trusted if all certificates in
125 * the chain are within the validity window and the parent trust manager also
126 * accepts the certificate.
127 *
128 * @param chain The peer certificate chain.
129 * @param authType The key exchange algorithm used.
130 *
131 * @throws CertificateException If the server certificate chain is not
132 * trusted.
133 */
134 public void checkServerTrusted(X509Certificate[] chain, String authType)
135 throws CertificateException
136 {
137 Date currentDate = new Date();
138 for (X509Certificate c : chain)
139 {
140 try
141 {
142 c.checkValidity(currentDate);
143 }
144 catch (CertificateExpiredException cee)
145 {
146 Message message = ERR_EXPCHECK_TRUSTMGR_SERVER_CERT_EXPIRED.get(
147 c.getSubjectDN().getName(), String.valueOf(c.getNotAfter()));
148 logError(message);
149
150 throw cee;
151 }
152 catch (CertificateNotYetValidException cnyve)
153 {
154 Message message = ERR_EXPCHECK_TRUSTMGR_SERVER_CERT_NOT_YET_VALID.get(
155 c.getSubjectDN().getName(), String.valueOf(c.getNotBefore()));
156 logError(message);
157
158 throw cnyve;
159 }
160 }
161
162 trustManager.checkServerTrusted(chain, authType);
163 }
164
165
166
167 /**
168 * Retrieves the set of CA certificates which are trusted for authenticating
169 * peers. This will be taken from the parent trust manager.
170 *
171 * @return A non-null (possibly empty) array of acceptable CA issuer
172 * certificates.
173 */
174 public X509Certificate[] getAcceptedIssuers()
175 {
176 return trustManager.getAcceptedIssuers();
177 }
178 }
179