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-2016 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  @Override
082  public void checkClientTrusted(X509Certificate[] chain, String authType)
083         throws CertificateException
084  {
085    Date currentDate = new Date();
086    for (X509Certificate c : chain)
087    {
088      try
089      {
090        c.checkValidity(currentDate);
091      }
092      catch (CertificateExpiredException cee)
093      {
094        logger.error(ERR_EXPCHECK_TRUSTMGR_CLIENT_CERT_EXPIRED,
095            c.getSubjectDN().getName(), c.getNotAfter());
096        throw cee;
097      }
098      catch (CertificateNotYetValidException cnyve)
099      {
100        logger.error(ERR_EXPCHECK_TRUSTMGR_CLIENT_CERT_NOT_YET_VALID,
101            c.getSubjectDN().getName(), c.getNotBefore());
102        throw cnyve;
103      }
104    }
105
106    trustManager.checkClientTrusted(chain, authType);
107  }
108
109
110
111  /**
112   * Determines whether to trust the peer based on the provided certificate
113   * chain.  In this case, the peer will only be trusted if all certificates in
114   * the chain are within the validity window and the parent trust manager also
115   * accepts the certificate.
116   *
117   * @param  chain     The peer certificate chain.
118   * @param  authType  The key exchange algorithm used.
119   *
120   * @throws  CertificateException  If the server certificate chain is not
121   *                                trusted.
122   */
123  @Override
124  public void checkServerTrusted(X509Certificate[] chain, String authType)
125         throws CertificateException
126  {
127    Date currentDate = new Date();
128    for (X509Certificate c : chain)
129    {
130      try
131      {
132        c.checkValidity(currentDate);
133      }
134      catch (CertificateExpiredException cee)
135      {
136        logger.error(ERR_EXPCHECK_TRUSTMGR_SERVER_CERT_EXPIRED,
137            c.getSubjectDN().getName(), c.getNotAfter());
138        throw cee;
139      }
140      catch (CertificateNotYetValidException cnyve)
141      {
142        logger.error(ERR_EXPCHECK_TRUSTMGR_SERVER_CERT_NOT_YET_VALID,
143            c.getSubjectDN().getName(), c.getNotBefore());
144        throw cnyve;
145      }
146    }
147
148    trustManager.checkServerTrusted(chain, authType);
149  }
150
151
152
153  /**
154   * Retrieves the set of CA certificates which are trusted for authenticating
155   * peers.  This will be taken from the parent trust manager.
156   *
157   * @return  A non-null (possibly empty) array of acceptable CA issuer
158   *          certificates.
159   */
160  @Override
161  public X509Certificate[] getAcceptedIssuers()
162  {
163    return trustManager.getAcceptedIssuers();
164  }
165}
166