View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.api.security.tls;
8   
9   import java.io.IOException;
10  import java.util.Properties;
11  
12  import org.apache.commons.logging.Log;
13  import org.apache.commons.logging.LogFactory;
14  
15  /**
16   * Move a {@link TlsConfiguration} to and from Properties (typically System Properties).
17   * This can be used to store TLS/SSL configuration for a library (eg. Javamail, which
18   * reads java.mail properties) or for later retrieval by {@link TlsPropertiesSocketFactory}.
19   */
20  public class TlsPropertiesMapper
21  {
22  
23      private static final String TRUST_NAME_SUFFIX = ".ssl.trustStore";
24      private static final String TRUST_TYPE_SUFFIX = ".ssl.trustStoreType";
25      private static final String TRUST_PASSWORD_SUFFIX = ".ssl.trustStorePassword";
26      private static final String TRUST_ALGORITHM_SUFFIX = ".ssl.trustManagerAlgorithm";
27  
28      private static final String KEY_NAME_SUFFIX = ".ssl.keyStore";
29      private static final String KEY_TYPE_SUFFIX = ".ssl.keyStoreType";
30      private static final String KEY_PASSWORD_SUFFIX = ".ssl.keyStorePassword";
31  
32      private Log logger = LogFactory.getLog(getClass());
33      private String namespace;
34  
35      public TlsPropertiesMapper(String namespace)
36      {
37          this.namespace = namespace;
38      }
39  
40      public void writeToProperties(Properties properties, TlsConfiguration configuration)
41      {
42          writeTrustStoreToProperties(properties, configuration);
43          writeKeyStoreToProperties(properties, configuration);
44      }
45  
46      public void readFromProperties(TlsConfiguration configuration, Properties properties) throws IOException
47      {
48          readTrustStoreFromProperties(configuration, properties);
49          readKeyStoreFromProperties(configuration, properties);
50      }
51  
52      private void writeTrustStoreToProperties(Properties properties, TlsConfiguration configuration)
53      {
54          String trustStoreName = configuration.getTrustStore();
55          String trustStorePassword = configuration.getTrustStorePassword();
56  
57          if (null == trustStoreName && !configuration.isExplicitTrustStoreOnly())
58          {
59              logger.info("Defaulting " + namespace + " trust store to client Key Store");
60              trustStoreName = configuration.getClientKeyStore();
61              trustStorePassword = configuration.getClientKeyStorePassword();
62          }
63          if (null != trustStoreName)
64          {
65              synchronized (properties)
66              {
67                  setProperty(properties, TRUST_NAME_SUFFIX, trustStoreName);
68                  setProperty(properties, TRUST_TYPE_SUFFIX, configuration.getTrustStoreType());
69                  setProperty(properties, TRUST_PASSWORD_SUFFIX, trustStorePassword);
70                  setProperty(properties, TRUST_ALGORITHM_SUFFIX, configuration.getTrustManagerAlgorithm());
71              }
72              logger.debug("Set Trust Store: " + namespace + TRUST_NAME_SUFFIX + " = " + trustStoreName);
73          }
74      }
75  
76      private void readTrustStoreFromProperties(TlsConfiguration configuration, Properties properties) 
77      throws IOException
78      {
79          configuration.setTrustStore(
80              getProperty(properties, TRUST_NAME_SUFFIX, configuration.getTrustStore()));
81          configuration.setTrustStoreType(
82              getProperty(properties, TRUST_TYPE_SUFFIX, configuration.getTrustStoreType()));
83          configuration.setTrustStorePassword(
84              getProperty(properties, TRUST_PASSWORD_SUFFIX, configuration.getTrustStorePassword()));
85          configuration.setTrustManagerAlgorithm(
86              getProperty(properties, TRUST_ALGORITHM_SUFFIX, configuration.getTrustManagerAlgorithm()));
87      }
88  
89      private void writeKeyStoreToProperties(Properties properties, TlsConfiguration configuration) 
90      {
91          if (null != configuration.getClientKeyStore())
92          {
93              synchronized (properties)
94              {
95                  setProperty(properties, KEY_NAME_SUFFIX, configuration.getClientKeyStore());
96                  setProperty(properties, KEY_TYPE_SUFFIX, configuration.getClientKeyStoreType());
97                  setProperty(properties, KEY_PASSWORD_SUFFIX, configuration.getClientKeyStorePassword());
98              }
99              logger.info("Set Key Store: " + namespace + KEY_NAME_SUFFIX + " = " + configuration.getClientKeyStore());
100         }
101     }
102 
103     // note the asymmetry here.  this preserves the semantics of the original implementation.
104 
105     // originally, the "client" keystore data were written to system properties (only) and
106     // used implicitly to construct sockets, while "non-client" keystore information was
107     // used explicitly.
108 
109     // now we construct some of those implicit sockets explicitly (as part of avoiding global
110     // configuration for tls across all transports).  in these cases we read the data needed
111     // from (namespaced) proeprties.  if we read that information back into "non-client" keystore
112     // data, even though it was written from "client" data, then we can use the same code in
113     // TlsConfiguration to generate the sockets in both cases.
114 
115     private void readKeyStoreFromProperties(TlsConfiguration configuration, Properties properties) 
116     throws IOException 
117     {
118         configuration.setKeyStore(
119             getProperty(properties, KEY_NAME_SUFFIX, configuration.getKeyStore()));
120         configuration.setKeyStoreType(
121             getProperty(properties, KEY_TYPE_SUFFIX, configuration.getKeyStoreType()));
122         configuration.setKeyStorePassword(
123             getProperty(properties, KEY_PASSWORD_SUFFIX, configuration.getKeyStorePassword()));
124     }
125 
126 
127     private void setProperty(Properties properties, String suffix, String value)
128     {
129         if (null != value)
130         {
131             properties.setProperty(namespace + suffix, value);
132             if (logger.isDebugEnabled())
133             {
134                 logger.debug(namespace + suffix + " <- " + value);
135             }
136         }
137     }
138 
139     private String getProperty(Properties properties, String suffix, String deflt)
140     {
141         String value = properties.getProperty(namespace + suffix);
142         if (null == value)
143         {
144             value = deflt;
145         }
146         if (logger.isDebugEnabled())
147         {
148             logger.debug(namespace + suffix + " -> " + value);
149         }
150         return value;
151     }
152 
153 }
154 
155