1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.client.bindings.spi;
20
21 import java.io.BufferedInputStream;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.InputStream;
25 import java.security.KeyStore;
26 import java.util.Enumeration;
27 import java.util.Locale;
28
29 import javax.net.ssl.KeyManagerFactory;
30 import javax.net.ssl.SSLContext;
31 import javax.net.ssl.SSLSocketFactory;
32
33 import org.apache.chemistry.opencmis.commons.SessionParameter;
34 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
35 import org.apache.chemistry.opencmis.commons.impl.IOUtils;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public class ClientCertificateAuthenticationProvider extends StandardAuthenticationProvider {
67 private static final long serialVersionUID = 1L;
68
69 private static final Logger LOG = LoggerFactory.getLogger(ClientCertificateAuthenticationProvider.class);
70
71 private SSLSocketFactory socketFactory;
72
73 @Override
74 public void setSession(BindingSession session) {
75 super.setSession(session);
76
77 if (socketFactory == null) {
78 Object keyfile = getSession().get(SessionParameter.CLIENT_CERT_KEYFILE);
79 if (keyfile instanceof String) {
80 Object passphrase = getSession().get(SessionParameter.CLIENT_CERT_PASSPHRASE);
81
82 String keyfileStr = ((String) keyfile).trim();
83 String passphraseStr = passphrase instanceof String ? ((String) passphrase).trim() : null;
84
85 socketFactory = createSSLSocketFactory(keyfileStr, passphraseStr);
86 }
87 }
88 }
89
90 @Override
91 public SSLSocketFactory getSSLSocketFactory() {
92 return socketFactory;
93 }
94
95 protected SSLSocketFactory createSSLSocketFactory(String keyFile, String passphrase) {
96 assert keyFile != null;
97
98 if (LOG.isDebugEnabled()) {
99 LOG.debug("Using key file '{}'", keyFile);
100 }
101
102 try {
103 char[] passphraseChars = passphrase == null ? null : passphrase.toCharArray();
104
105 KeyStore keyStore;
106
107 String ext = getExtension(keyFile);
108 if ("p12".equals(ext) || "pfx".equals(ext)) {
109 keyStore = KeyStore.getInstance("PKCS12");
110 } else {
111 keyStore = KeyStore.getInstance("JKS");
112 }
113
114
115 InputStream keyStream = null;
116 try {
117 keyStream = new BufferedInputStream(new FileInputStream(keyFile));
118 keyStore.load(keyStream, passphraseChars);
119 } finally {
120 IOUtils.closeQuietly(keyStream);
121 }
122
123 if (LOG.isDebugEnabled()) {
124 LOG.debug("Key store type: {}", keyStore.getType());
125
126 StringBuilder sb = new StringBuilder();
127 Enumeration<String> aliases = keyStore.aliases();
128 while (aliases.hasMoreElements()) {
129 if (sb.length() > 0) {
130 sb.append(", ");
131 }
132 sb.append(aliases.nextElement());
133 }
134
135 LOG.debug("Aliases in key store: {}", sb.toString());
136 }
137
138
139 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
140 keyManagerFactory.init(keyStore, passphraseChars);
141
142 SSLContext context = SSLContext.getInstance("TLS");
143 context.init(keyManagerFactory.getKeyManagers(), null, null);
144
145 return context.getSocketFactory();
146 } catch (FileNotFoundException fnfe) {
147 throw new CmisRuntimeException("Key file '" + keyFile + "' not found!", fnfe);
148 } catch (Exception e) {
149 throw new CmisRuntimeException("Cannot set up client certificate: " + e.toString(), e);
150 }
151 }
152
153 private String getExtension(String filename) {
154 int x = filename.lastIndexOf('.');
155 if (x > -1) {
156 return filename.substring(x + 1).toLowerCase(Locale.ENGLISH);
157 }
158
159 return null;
160 }
161 }