You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2014/06/13 13:15:16 UTC

git commit: [CXF-5311] Support for loading private or public key handlers in JAX-RS providers using context properties, based on the CXF WS-Sec/WSS4J idea

Repository: cxf
Updated Branches:
  refs/heads/master 66e469674 -> 0ccdc3930


[CXF-5311] Support for loading private or public key handlers in JAX-RS providers using context properties, based on the CXF WS-Sec/WSS4J idea


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/0ccdc393
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/0ccdc393
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/0ccdc393

Branch: refs/heads/master
Commit: 0ccdc3930f8f0dcee14140467be83d89c625dc46
Parents: 66e4696
Author: Sergey Beryozkin <sb...@talend.com>
Authored: Fri Jun 13 12:14:58 2014 +0100
Committer: Sergey Beryozkin <sb...@talend.com>
Committed: Fri Jun 13 12:14:58 2014 +0100

----------------------------------------------------------------------
 .../rs/security/oauth2/jwe/RSAJweDecryptor.java |  3 +-
 .../jwt/jaxrs/AbstractJweDecryptingFilter.java  | 34 ++++++++-
 .../oauth2/jwt/jaxrs/JweWriterInterceptor.java  | 36 ++++++++-
 .../jwt/jaxrs/JwsMessageBodyProvider.java       | 63 +++++++++++++++-
 .../oauth2/jwe/JweCompactReaderWriterTest.java  |  8 +-
 .../oauth2/utils/crypto/CryptoUtils.java        | 78 +++++++++++++++++---
 .../crypto/PrivateKeyPasswordProvider.java      | 25 +++++++
 7 files changed, 226 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/0ccdc393/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java
index f0ea144..0bba471 100644
--- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java
@@ -19,7 +19,6 @@
 package org.apache.cxf.rs.security.oauth2.jwe;
 
 import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
 
 
 public class RSAJweDecryptor extends WrappedKeyJweDecryptor {
@@ -36,6 +35,6 @@ public class RSAJweDecryptor extends WrappedKeyJweDecryptor {
     }
     
     protected int getKeyCipherBlockSize() {
-        return ((RSAPublicKey)getCekDecryptionKey()).getModulus().toByteArray().length;
+        return ((RSAPrivateKey)getCekDecryptionKey()).getModulus().toByteArray().length;
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/0ccdc393/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java
index 296f12f..5ef8993 100644
--- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java
@@ -20,16 +20,31 @@ package org.apache.cxf.rs.security.oauth2.jwt.jaxrs;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.security.PrivateKey;
 
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
 import org.apache.cxf.rs.security.oauth2.jwe.JweDecryptionOutput;
 import org.apache.cxf.rs.security.oauth2.jwe.JweDecryptor;
 import org.apache.cxf.rs.security.oauth2.jwe.JweHeaders;
+import org.apache.cxf.rs.security.oauth2.jwe.WrappedKeyJweDecryptor;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.PrivateKeyPasswordProvider;
 
 public class AbstractJweDecryptingFilter {
+    private static final String RSSEC_ENCRYPTION_PROPS = "rs-security.encryption.properties";
+    private static final String RSSEC_KEY_PSWD_PROVIDER = "org.apache.rs.security.crypto.private.provider";
+    
     private JweDecryptor decryptor;
     protected byte[] decrypt(InputStream is) throws IOException {
-        JweDecryptionOutput out = decryptor.decrypt(new String(IOUtils.readBytesFromStream(is), "UTF-8"));
+        JweDecryptor theDecryptor = getInitializedDecryptor();
+        if (theDecryptor == null) {
+            throw new SecurityException();
+        }
+        JweDecryptionOutput out = theDecryptor.decrypt(new String(IOUtils.readBytesFromStream(is), "UTF-8"));
         validateHeaders(out.getHeaders());
         return out.getContent();
     }
@@ -40,5 +55,22 @@ public class AbstractJweDecryptingFilter {
     public void setDecryptor(JweDecryptor decryptor) {
         this.decryptor = decryptor;
     }
+    protected JweDecryptor getInitializedDecryptor() {
+        if (decryptor != null) {
+            return decryptor;    
+        } 
+        Message m = JAXRSUtils.getCurrentMessage();
+        if (m == null) {
+            return null;
+        }
+        String propLoc = (String)m.getContextualProperty(RSSEC_ENCRYPTION_PROPS);
+        if (propLoc == null) {
+            return null;
+        }
+        PrivateKeyPasswordProvider cb = (PrivateKeyPasswordProvider)m.getContextualProperty(RSSEC_KEY_PSWD_PROVIDER);
+        Bus bus = (Bus)m.getExchange().get(Endpoint.class).get(Bus.class.getName());
+        PrivateKey pk = CryptoUtils.loadPrivateKey(propLoc, bus, cb);
+        return new WrappedKeyJweDecryptor(pk);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/0ccdc393/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java
index be3f2eb..e4698cb 100644
--- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java
@@ -21,16 +21,26 @@ package org.apache.cxf.rs.security.oauth2.jwt.jaxrs;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.security.PublicKey;
 
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.ext.WriterInterceptor;
 import javax.ws.rs.ext.WriterInterceptorContext;
 
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
 import org.apache.cxf.rs.security.oauth2.jwe.JweEncryptor;
+import org.apache.cxf.rs.security.oauth2.jwe.JweHeaders;
+import org.apache.cxf.rs.security.oauth2.jwe.WrappedKeyJweEncryptor;
+import org.apache.cxf.rs.security.oauth2.jwt.Algorithm;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
 
 public class JweWriterInterceptor implements WriterInterceptor {
+    private static final String RSSEC_ENCRYPTION_PROPS = "rs-security.encryption.properties";
     private JweEncryptor encryptor;
 
     @Override
@@ -39,10 +49,34 @@ public class JweWriterInterceptor implements WriterInterceptor {
         CachedOutputStream cos = new CachedOutputStream(); 
         ctx.setOutputStream(cos);
         ctx.proceed();
-        String jweContent = encryptor.encrypt(cos.getBytes());
+        
+        JweEncryptor theEncryptor = getInitializedEncryptor();
+        if (theEncryptor == null) {
+            throw new SecurityException();
+        }
+        String jweContent = theEncryptor.encrypt(cos.getBytes());
         IOUtils.copy(new ByteArrayInputStream(jweContent.getBytes("UTF-8")), actualOs);
         actualOs.flush();
         // TODO: figure out what to do with the content type
     }
     
+    protected JweEncryptor getInitializedEncryptor() {
+        if (encryptor != null) {
+            return encryptor;    
+        } 
+        Message m = JAXRSUtils.getCurrentMessage();
+        if (m == null) {
+            return null;
+        }
+        String propLoc = (String)m.getContextualProperty(RSSEC_ENCRYPTION_PROPS);
+        if (propLoc == null) {
+            return null;
+        }
+        Bus bus = (Bus)m.getExchange().get(Endpoint.class).get(Bus.class.getName());
+        PublicKey pk = CryptoUtils.loadPublicKey(propLoc, bus);
+        return new WrappedKeyJweEncryptor(new JweHeaders(Algorithm.RSA_OAEP.getJwtName(),
+                                                         Algorithm.A256GCM.getJwtName()), 
+                                          pk);
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/0ccdc393/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsMessageBodyProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsMessageBodyProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsMessageBodyProvider.java
index 96c171d..96bd86f 100644
--- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsMessageBodyProvider.java
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsMessageBodyProvider.java
@@ -24,6 +24,8 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
+import java.security.PrivateKey;
+import java.security.PublicKey;
 
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
@@ -31,16 +33,26 @@ import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.MessageBodyWriter;
 
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
 import org.apache.cxf.rs.security.oauth2.jws.JwsCompactConsumer;
 import org.apache.cxf.rs.security.oauth2.jws.JwsCompactProducer;
 import org.apache.cxf.rs.security.oauth2.jws.JwsSignatureProvider;
 import org.apache.cxf.rs.security.oauth2.jws.JwsSignatureVerifier;
+import org.apache.cxf.rs.security.oauth2.jws.PrivateKeyJwsSignatureProvider;
+import org.apache.cxf.rs.security.oauth2.jws.PublicKeyJwsSignatureVerifier;
 import org.apache.cxf.rs.security.oauth2.jwt.JwtToken;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.PrivateKeyPasswordProvider;
 
 public class JwsMessageBodyProvider implements 
     MessageBodyWriter<JwtToken>, MessageBodyReader<JwtToken> {
-
+    private static final String RSSEC_SIGNATURE_PROPS = "rs-security.signature.properties";
+    private static final String RSSEC_KEY_PSWD_PROVIDER = "org.apache.rs.security.crypto.private.provider";
+    
     private JwsSignatureProvider sigProvider;
     private JwsSignatureVerifier sigVerifier;
     
@@ -53,8 +65,12 @@ public class JwsMessageBodyProvider implements
     public JwtToken readFrom(Class<JwtToken> cls, Type t, Annotation[] anns, MediaType mt,
                              MultivaluedMap<String, String> headers, InputStream is) throws IOException,
         WebApplicationException {
+        JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier();
+        if (theSigVerifier == null) {
+            throw new SecurityException();
+        }
         JwsCompactConsumer p = new JwsCompactConsumer(IOUtils.readStringFromStream(is));
-        p.verifySignatureWith(sigVerifier);
+        p.verifySignatureWith(theSigVerifier);
         return p.getJwtToken();
     }
 
@@ -72,8 +88,13 @@ public class JwsMessageBodyProvider implements
     public void writeTo(JwtToken token, Class<?> cls, Type type, Annotation[] anns, MediaType mt,
                         MultivaluedMap<String, Object> headers, OutputStream os) throws IOException,
         WebApplicationException {
+        
+        JwsSignatureProvider theSigProvider = getInitializedSigProvider();
+        if (theSigProvider == null) {
+            throw new SecurityException();
+        }
         JwsCompactProducer p = new JwsCompactProducer(token);
-        p.signWith(sigProvider);
+        p.signWith(theSigProvider);
         IOUtils.copy(new ByteArrayInputStream(p.getSignedEncodedToken().getBytes("UTF-8")), os);
     }
 
@@ -87,4 +108,40 @@ public class JwsMessageBodyProvider implements
         this.sigVerifier = sigVerifier;
     }
 
+    protected JwsSignatureProvider getInitializedSigProvider() {
+        if (sigProvider != null) {
+            return sigProvider;    
+        } 
+        Message m = JAXRSUtils.getCurrentMessage();
+        if (m == null) {
+            return null;
+        }
+        String propLoc = (String)m.getContextualProperty(RSSEC_SIGNATURE_PROPS);
+        if (propLoc == null) {
+            return null;
+        }
+        
+        PrivateKeyPasswordProvider cb = (PrivateKeyPasswordProvider)m.getContextualProperty(RSSEC_KEY_PSWD_PROVIDER);
+        Bus bus = (Bus)m.getExchange().get(Endpoint.class).get(Bus.class.getName());
+        PrivateKey pk = CryptoUtils.loadPrivateKey(propLoc, bus, cb);
+        return new PrivateKeyJwsSignatureProvider(pk);
+    }
+    
+    protected JwsSignatureVerifier getInitializedSigVerifier() {
+        if (sigVerifier != null) {
+            return sigVerifier;    
+        } 
+        Message m = JAXRSUtils.getCurrentMessage();
+        if (m == null) {
+            return null;
+        }
+        String propLoc = (String)m.getContextualProperty(RSSEC_SIGNATURE_PROPS);
+        if (propLoc == null) {
+            return null;
+        }
+        
+        Bus bus = (Bus)m.getExchange().get(Endpoint.class).get(Bus.class.getName());
+        PublicKey pk = CryptoUtils.loadPublicKey(propLoc, bus);
+        return new PublicKeyJwsSignatureVerifier(pk);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/0ccdc393/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java
index 1ac3e6a..981ffd8 100644
--- a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java
+++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java
@@ -79,7 +79,7 @@ public class JweCompactReaderWriterTest extends Assert {
         final String specPlainText = "The true sign of intelligence is not knowledge but imagination.";
         String jweContent = encryptContent(specPlainText, true);
         
-        decrypt(jweContent, specPlainText);
+        decrypt(jweContent, specPlainText, true);
     }
     @Test
     public void testDirectKeyEncryptDecrypt() throws Exception {
@@ -93,7 +93,7 @@ public class JweCompactReaderWriterTest extends Assert {
     @Test
     public void testEncryptDecryptJwsToken() throws Exception {
         String jweContent = encryptContent(JwsCompactReaderWriterTest.ENCODED_TOKEN_SIGNED_BY_MAC, false);
-        decrypt(jweContent, JwsCompactReaderWriterTest.ENCODED_TOKEN_SIGNED_BY_MAC);
+        decrypt(jweContent, JwsCompactReaderWriterTest.ENCODED_TOKEN_SIGNED_BY_MAC, false);
     }
     
     private String encryptContent(String content, boolean createIfException) throws Exception {
@@ -116,9 +116,9 @@ public class JweCompactReaderWriterTest extends Assert {
         DirectKeyJweEncryptor encryptor = new DirectKeyJweEncryptor(key, INIT_VECTOR);
         return encryptor.encryptText(content);
     }
-    private void decrypt(String jweContent, String plainContent) throws Exception {
+    private void decrypt(String jweContent, String plainContent, boolean unwrap) throws Exception {
         RSAPrivateKey privateKey = CryptoUtils.getRSAPrivateKey(RSA_MODULUS_ENCODED, RSA_PRIVATE_EXPONENT_ENCODED);
-        RSAJweDecryptor decryptor = new RSAJweDecryptor(privateKey);
+        RSAJweDecryptor decryptor = new RSAJweDecryptor(privateKey, unwrap);
         String decryptedText = decryptor.decrypt(jweContent).getContentText();
         assertEquals(decryptedText, plainContent);
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/0ccdc393/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java
index 1527f79..924cd1a 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java
@@ -36,6 +36,7 @@ import java.security.interfaces.RSAPublicKey;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.RSAPrivateKeySpec;
 import java.security.spec.RSAPublicKeySpec;
+import java.util.Properties;
 import java.util.logging.Logger;
 
 import javax.crypto.Cipher;
@@ -44,10 +45,12 @@ import javax.crypto.SecretKey;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.CompressionUtils;
 import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
 import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
 
 
@@ -55,7 +58,12 @@ import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
  * Encryption helpers
  */
 public final class CryptoUtils {
-    
+    private static final String RSSEC_KEY_STORE_TYPE = "org.apache.rs.security.crypto.keystore.type";
+    private static final String RSSEC_KEY_STORE_PSWD = "org.apache.rs.security.crypto.keystore.password";
+    private static final String RSSEC_KEY_PSWD = "org.apache.rs.security.crypto.private.password";
+    private static final String RSSEC_KEY_STORE_ALIAS = "org.apache.rs.security.crypto.keystore.alias";
+    private static final String RSSEC_KEY_STORE_FILE = "org.apache.rs.security.crypto.keystore.file";
+        
     private static final Logger LOG = LogUtils.getL7dLogger(CryptoUtils.class);
     
     private CryptoUtils() {
@@ -120,27 +128,76 @@ public final class CryptoUtils {
         }    
     }
     
-    public static Certificate loadCertificate(InputStream storeLocation, char[] storePassword, String alias) {
+    public static Certificate loadCertificate(InputStream storeLocation, char[] storePassword, String alias,
+                                              String storeType) {
         try {
-            KeyStore keyStore = loadKeyStore(storeLocation, storePassword);
+            KeyStore keyStore = loadKeyStore(storeLocation, storePassword, storeType);
             return keyStore.getCertificate(alias);
         } catch (Exception ex) { 
             throw new SecurityException(ex);
         }
     }
     
-    public static PublicKey loadPublicKey(InputStream storeLocation, char[] storePassword, String alias) {
+    public static PublicKey loadPublicKey(InputStream storeLocation, char[] storePassword, String alias,
+                                          String storeType) {
         try {
-            return loadCertificate(storeLocation, storePassword, alias).getPublicKey();
+            return loadCertificate(storeLocation, storePassword, alias, storeType).getPublicKey();
         } catch (Exception ex) { 
             throw new SecurityException(ex);
         }
     }
+    public static Certificate loadCertificate(String propertiesLocation, Bus bus) {
+        try {
+            Properties props = loadProperties(propertiesLocation, bus);
+            String keyStoreType = props.getProperty(RSSEC_KEY_STORE_TYPE);
+            String keyStoreLoc = props.getProperty(RSSEC_KEY_STORE_FILE);
+            String keyStorePswd = props.getProperty(RSSEC_KEY_STORE_PSWD);
+            String alias = props.getProperty(RSSEC_KEY_STORE_ALIAS);
+            InputStream is = ResourceUtils.getResourceStream(keyStoreLoc, bus);
+            return loadCertificate(is, keyStorePswd.toCharArray(), alias, keyStoreType);
+        } catch (Exception ex) { 
+            throw new SecurityException(ex);
+        }    
+    }
+    public static PublicKey loadPublicKey(String propertiesLocation, Bus bus) {
+        try {
+            return loadCertificate(propertiesLocation, bus).getPublicKey();
+        } catch (Exception ex) { 
+            throw new SecurityException(ex);
+        }    
+    }
+    public static PrivateKey loadPrivateKey(String propertiesLocation, Bus bus, 
+                                            PrivateKeyPasswordProvider provider) {
+        try {
+            
+            Properties props = loadProperties(propertiesLocation, bus);
+            String keyStoreType = props.getProperty(RSSEC_KEY_STORE_TYPE);
+            String keyStoreLoc = props.getProperty(RSSEC_KEY_STORE_FILE);
+            String keyStorePswd = props.getProperty(RSSEC_KEY_STORE_PSWD);
+            String keyPswd = props.getProperty(RSSEC_KEY_PSWD);
+            String alias = props.getProperty(RSSEC_KEY_STORE_ALIAS);
+            InputStream is = ResourceUtils.getResourceStream(keyStoreLoc, bus);
+            char[] keyPswdChars = provider != null ? provider.getPassword(props) 
+                : keyPswd != null ? keyPswd.toCharArray() : null;    
+            return loadPrivateKey(is, keyStorePswd.toCharArray(), keyPswdChars, alias, keyStoreType);
+        } catch (Exception ex) { 
+            throw new SecurityException(ex);
+        }    
+    }
+    private static Properties loadProperties(String propertiesLocation, Bus bus) throws Exception {
+        Properties props = new Properties();
+        InputStream is = ResourceUtils.getResourceStream(propertiesLocation, bus);
+        props.load(is);
+        return props;
+    }
     
-    public static PrivateKey loadPrivateKey(InputStream storeLocation, char[] storePassword, 
-                                          char[] keyPassword, String alias) {
+    public static PrivateKey loadPrivateKey(InputStream storeLocation, 
+                                            char[] storePassword, 
+                                            char[] keyPassword, 
+                                            String alias,
+                                            String storeType) {
         try {
-            KeyStore keyStore = loadKeyStore(storeLocation, storePassword);
+            KeyStore keyStore = loadKeyStore(storeLocation, storePassword, storeType);
             KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
                 keyStore.getEntry(alias, new KeyStore.PasswordProtection(keyPassword));
             return pkEntry.getPrivateKey();
@@ -150,8 +207,9 @@ public final class CryptoUtils {
     }
     
     
-    private static KeyStore loadKeyStore(InputStream storeLocation, char[] storePassword) throws Exception {
-        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+    private static KeyStore loadKeyStore(InputStream storeLocation, char[] storePassword, String type) 
+        throws Exception {
+        KeyStore ks = KeyStore.getInstance(type == null ? KeyStore.getDefaultType() : type);
         ks.load(storeLocation, storePassword);
         return ks;
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/0ccdc393/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/PrivateKeyPasswordProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/PrivateKeyPasswordProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/PrivateKeyPasswordProvider.java
new file mode 100644
index 0000000..e727464
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/PrivateKeyPasswordProvider.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.utils.crypto;
+
+import java.util.Properties;
+
+public interface PrivateKeyPasswordProvider {
+    char[] getPassword(Properties storeProperties); 
+}