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