PageRenderTime 109ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/jgroups/auth/X509Token.java

https://github.com/jadahl/jgroups-android
Java | 245 lines | 189 code | 31 blank | 25 comment | 40 complexity | 51a331f96a31688d3ff1909a53266be3 MD5 | raw file
Possible License(s): LGPL-2.1
  1. package org.jgroups.auth;
  2. import org.jgroups.util.Util;
  3. import org.jgroups.Message;
  4. import javax.crypto.Cipher;
  5. import java.io.*;
  6. import java.util.Properties;
  7. import java.security.cert.X509Certificate;
  8. import java.security.PrivateKey;
  9. import java.security.KeyStore;
  10. /**
  11. * <p>
  12. * This is an example of using a preshared token that is encrypted using an X509 certificate for authentication purposes. All members of the group have to have the same string value in the JGroups config.
  13. * </p>
  14. * <p>
  15. * This example uses certificates contained within a specified keystore. Configuration parameters for this example are shown below:
  16. * </p>
  17. * <ul>
  18. * <li>keystore_type = JKS(default)/PKCS12 - see http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpec.html#AppA</li>
  19. * <li>keystore_path (required) = the location of the keystore</li>
  20. * <li>keystore_password (required) = the password of the keystore</li>
  21. * <li>cert_alias (required) = the alias of the certification within the keystore</li>
  22. * <li>cert_password = the password of the certification within the keystore</li>
  23. * <li>auth_value (required) = the string to encrypt</li>
  24. * <li>cipher_type = RSA(default)/AES/Blowfish/DES/DESede/PBEWithMD5AndDES/PBEWithHmacSHA1AndDESede/RC2/RC4/RC5 - see http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppA</li>
  25. * </ul>
  26. * @see org.jgroups.auth.AuthToken
  27. * @author Chris Mills
  28. */
  29. public class X509Token extends AuthToken {
  30. public static final String KEYSTORE_TYPE = "keystore_type";
  31. public static final String KEYSTORE_PATH = "keystore_path";
  32. public static final String KEYSTORE_PASSWORD = "keystore_password";
  33. public static final String CERT_ALIAS = "cert_alias";
  34. public static final String CERT_PASSWORD = "cert_password";
  35. public static final String TOKEN_ATTR = "auth_value";
  36. public static final String CIPHER_TYPE = "cipher_type";
  37. private boolean valueSet = false;
  38. private String keystore_type = null;
  39. private String cert_alias = null;
  40. private String keystore_path = null;
  41. private String token_attr = null;
  42. private String cipher_type = null;
  43. private byte[] encryptedToken = null;
  44. private char[] cert_password = null;
  45. private char[] keystore_password = null;
  46. private Cipher cipher = null;
  47. private PrivateKey certPrivateKey = null;
  48. private X509Certificate certificate = null;
  49. public X509Token() {
  50. //need an empty constructor
  51. }
  52. public void setValue(Properties properties) {
  53. if(log.isDebugEnabled()){
  54. log.debug("setting values on X509Token object");
  55. }
  56. if(properties.containsKey(TOKEN_ATTR)){
  57. this.token_attr = (String) properties.get(TOKEN_ATTR);
  58. properties.remove(TOKEN_ATTR);
  59. if(log.isDebugEnabled()){
  60. log.debug("token_attr = " + this.token_attr);
  61. }
  62. }
  63. if(properties.containsKey(KEYSTORE_TYPE)){
  64. this.keystore_type = (String) properties.get(KEYSTORE_TYPE);
  65. properties.remove(KEYSTORE_TYPE);
  66. if(log.isDebugEnabled()){
  67. log.debug("keystore_type = " + this.keystore_type);
  68. }
  69. }else{
  70. this.keystore_type = "JKS";
  71. if(log.isDebugEnabled()){
  72. log.debug("keystore_type = " + this.keystore_type);
  73. }
  74. }
  75. if(properties.containsKey(KEYSTORE_PATH)){
  76. this.keystore_path = (String) properties.get(KEYSTORE_PATH);
  77. properties.remove(KEYSTORE_PATH);
  78. if(log.isDebugEnabled()){
  79. log.debug("keystore_path = " + this.keystore_path);
  80. }
  81. }
  82. if(properties.containsKey(KEYSTORE_PASSWORD)){
  83. this.keystore_password = ((String) properties.get(KEYSTORE_PASSWORD)).toCharArray();
  84. properties.remove(KEYSTORE_PASSWORD);
  85. if(log.isDebugEnabled()){
  86. log.debug("keystore_password = " + this.keystore_password);
  87. }
  88. }
  89. if(properties.containsKey(CERT_ALIAS)){
  90. this.cert_alias = (String) properties.get(CERT_ALIAS);
  91. properties.remove(CERT_ALIAS);
  92. if(log.isDebugEnabled()){
  93. log.debug("cert_alias = " + this.cert_alias);
  94. }
  95. }
  96. if(properties.containsKey(CERT_PASSWORD)){
  97. this.cert_password = ((String) properties.get(CERT_PASSWORD)).toCharArray();
  98. properties.remove(CERT_PASSWORD);
  99. if(log.isDebugEnabled()){
  100. log.debug("cert_password = " + this.cert_password);
  101. }
  102. }else{
  103. this.cert_password = this.keystore_password;
  104. if(log.isDebugEnabled()){
  105. log.debug("cert_password = " + this.cert_password);
  106. }
  107. }
  108. if(properties.containsKey(CIPHER_TYPE)){
  109. this.cipher_type = (String) properties.get(CIPHER_TYPE);
  110. properties.remove(CIPHER_TYPE);
  111. if(log.isDebugEnabled()){
  112. log.debug("cipher_type = " + this.cipher_type);
  113. }
  114. }else{
  115. this.cipher_type = "RSA";
  116. if(log.isDebugEnabled()){
  117. log.debug("cipher_type = " + this.cipher_type);
  118. }
  119. }
  120. if(getCertificate()){
  121. this.valueSet = true;
  122. if(log.isDebugEnabled()){
  123. log.debug("X509Token created correctly");
  124. }
  125. }
  126. }
  127. public String getName() {
  128. return "org.jgroups.auth.X509Token";
  129. }
  130. public boolean authenticate(AuthToken token, Message msg) {
  131. if (!this.valueSet) {
  132. if(log.isFatalEnabled()){
  133. log.fatal("X509Token not setup correctly - check token attrs");
  134. }
  135. return false;
  136. }
  137. if((token != null) && (token instanceof X509Token)){
  138. //got a valid X509 token object
  139. X509Token serverToken = (X509Token)token;
  140. if(!serverToken.valueSet){
  141. if(log.isFatalEnabled()){
  142. log.fatal("X509Token - recieved token not valid");
  143. }
  144. return false;
  145. }
  146. try{
  147. if(log.isDebugEnabled()){
  148. log.debug("setting cipher to decrypt mode");
  149. }
  150. this.cipher.init(Cipher.DECRYPT_MODE, this.certPrivateKey);
  151. String serverBytes = new String(this.cipher.doFinal(serverToken.encryptedToken));
  152. if((serverBytes != null) && (serverBytes.equalsIgnoreCase(this.token_attr))){
  153. if(log.isDebugEnabled()){
  154. log.debug("X509 authentication passed");
  155. }
  156. return true;
  157. }
  158. }catch(Exception e){
  159. if(log.isFatalEnabled()){
  160. log.fatal(e);
  161. }
  162. }
  163. }
  164. if(log.isWarnEnabled()){
  165. log.warn("X509 authentication failed");
  166. }
  167. return false;
  168. }
  169. public void writeTo(DataOutputStream out) throws IOException {
  170. if(log.isDebugEnabled()){
  171. log.debug("X509Token writeTo()");
  172. }
  173. Util.writeByteBuffer(this.encryptedToken, out);
  174. }
  175. public void readFrom(DataInputStream in) throws IOException, IllegalAccessException, InstantiationException {
  176. if(log.isDebugEnabled()){
  177. log.debug("X509Token readFrom()");
  178. }
  179. this.encryptedToken = Util.readByteBuffer(in);
  180. this.valueSet = true;
  181. }
  182. /**
  183. * Used during setup to get the certification from the keystore and encrypt the auth_value with the private key
  184. * @return true if the certificate was found and the string encypted correctly otherwise returns false
  185. */
  186. private boolean getCertificate() {
  187. try{
  188. KeyStore store = KeyStore.getInstance(this.keystore_type);
  189. java.io.FileInputStream fis = new java.io.FileInputStream(this.keystore_path);
  190. store.load(fis, this.keystore_password);
  191. this.cipher = Cipher.getInstance(this.cipher_type);
  192. this.certificate = (X509Certificate) store.getCertificate(this.cert_alias);
  193. if(log.isDebugEnabled()){
  194. log.debug("certificate = " + this.certificate.toString());
  195. }
  196. this.cipher.init(Cipher.ENCRYPT_MODE, this.certificate);
  197. this.encryptedToken = this.cipher.doFinal(this.token_attr.getBytes());
  198. if(log.isDebugEnabled()){
  199. log.debug("encryptedToken = " + this.encryptedToken);
  200. }
  201. KeyStore.PrivateKeyEntry privateKey = (KeyStore.PrivateKeyEntry)store.getEntry(this.cert_alias, new KeyStore.PasswordProtection(this.cert_password));
  202. this.certPrivateKey = privateKey.getPrivateKey();
  203. if(log.isDebugEnabled()){
  204. log.debug("certPrivateKey = " + this.certPrivateKey.toString());
  205. }
  206. return true;
  207. }catch(Exception e){
  208. if(log.isFatalEnabled()){
  209. log.fatal(e);
  210. }
  211. return false;
  212. }
  213. }
  214. }