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