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