2 * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * ShibHttpHook - Receive callbacks from OpenSAML HTTP Session processing.
20 package edu.internet2.middleware.shibboleth.serviceprovider;
22 import java.net.HttpURLConnection;
23 import java.net.Socket;
24 import java.security.KeyManagementException;
25 import java.security.NoSuchAlgorithmException;
26 import java.security.Principal;
27 import java.security.PrivateKey;
28 import java.security.cert.CertificateException;
29 import java.security.cert.X509Certificate;
31 import javax.net.ssl.HttpsURLConnection;
32 import javax.net.ssl.KeyManager;
33 import javax.net.ssl.SSLContext;
34 import javax.net.ssl.SSLSocketFactory;
35 import javax.net.ssl.TrustManager;
36 import javax.net.ssl.X509KeyManager;
37 import javax.net.ssl.X509TrustManager;
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpServletResponse;
41 import org.apache.log4j.Logger;
42 import org.opensaml.SAMLException;
43 import org.opensaml.SAMLSOAPHTTPBinding.HTTPHook;
45 import edu.internet2.middleware.shibboleth.common.Credential;
46 import edu.internet2.middleware.shibboleth.common.Credentials;
47 import edu.internet2.middleware.shibboleth.common.Trust;
48 import edu.internet2.middleware.shibboleth.metadata.AttributeAuthorityDescriptor;
51 * A callback object added to the SAML Binding by Shib. During
52 * HTTP session establishment and Request/Response processing
53 * to the AA, SAML calls these exists. This code traps HTTPS
54 * sessions and adds a JSSE TrustManager to process Certificates.
56 * @author Howard Gilbert
59 public class ShibHttpHook implements HTTPHook {
61 private static Logger log = Logger.getLogger(HTTPHook.class);
63 ServiceProviderContext context = ServiceProviderContext.getInstance();
64 ServiceProviderConfig config = context.getServiceProviderConfig();
65 Credentials credentials = config.getCredentials();
66 AttributeAuthorityDescriptor role;
72 public ShibHttpHook(AttributeAuthorityDescriptor role, Trust trust) {
78 public boolean incoming(HttpServletRequest r, Object globalCtx,
79 Object callCtx) throws SAMLException {
84 public boolean outgoing(HttpServletResponse r, Object globalCtx,
85 Object callCtx) throws SAMLException {
90 public boolean incoming(HttpURLConnection conn, Object globalCtx,
91 Object callCtx) throws SAMLException {
97 * After the URLConnection has been initialized and before
98 * the connect() method is called, this exit has a chance to
99 * do additional processing.
101 * <p>If this is an HTTPS session, configure the SocketFactory
102 * to use a custom TrustManager for Certificate processing.</p>
104 public boolean outgoing(HttpURLConnection conn, Object globalCtx,
105 Object callCtx) throws SAMLException {
106 if (!(conn instanceof HttpsURLConnection)) {
107 return true; // http: sessions need no processing
109 HttpsURLConnection sslconn = (HttpsURLConnection) conn;
110 SSLContext sslContext = null;
112 sslContext = SSLContext.getInstance("SSL");
113 } catch (NoSuchAlgorithmException e) {
114 log.error("Cannot find required SSL support");
117 TrustManager[] tms = new TrustManager[] {new ShibTrustManager()};
118 KeyManager[] kms = new KeyManager[] {new ShibKeyManager()};
120 sslContext.init(kms,tms,new java.security.SecureRandom());
121 } catch (KeyManagementException e) {
124 SSLSocketFactory socketFactory = sslContext.getSocketFactory();
125 sslconn.setSSLSocketFactory(socketFactory);
130 * Called to select the Client Certificate the SP will present to
133 * <p>Normally a user KeyManager extends some class backed by a
134 * KeyStore. It just chooses an alias, and lets the parent class
135 * do the dirty work of extracting the Certificate chain from the
136 * backing file. However, in Shibboleth the SP Credentials come
137 * from the configuration file and are in memory. There is no
138 * meaningful alias, so we make one up.
140 class ShibKeyManager implements X509KeyManager {
142 public String fred ="Fred";
143 public String[] freds = {fred};
145 public String[] getClientAliases(String arg0, Principal[] arg1) {
149 public String chooseClientAlias(String[] arg0, Principal[] arg1, Socket arg2) {
153 public String[] getServerAliases(String arg0, Principal[] arg1) {
157 public String chooseServerAlias(String arg0, Principal[] arg1, Socket arg2) {
161 public X509Certificate[] getCertificateChain(String arg0) {
162 Credential credential = credentials.getCredential();
163 X509Certificate[] certificateChain = credential.getX509CertificateChain();
164 return certificateChain;
167 public PrivateKey getPrivateKey(String arg0) {
168 // TODO Get the SP Private Key from the Credentials object.
169 Credential credential = credentials.getCredential();
170 PrivateKey privateKey = credential.getPrivateKey();
177 * Called to approve or reject the Server Certificate of the AA.
179 class ShibTrustManager implements X509TrustManager {
181 public X509Certificate[] getAcceptedIssuers() {
182 // Not needed, the Server has only one Certificate to send us.
183 return new X509Certificate[0];
186 public void checkClientTrusted(X509Certificate[] arg0, String arg1)
187 throws CertificateException {
188 // Not used, we are the client
191 public void checkServerTrusted(X509Certificate[] certs, String arg1)
192 throws CertificateException {
193 if (trust.validate(certs[0],certs,role))
195 //throw new CertificateException("Cannot validate AA Server Certificate in Metadata");