cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r1562902 - in /cxf/trunk: core/src/main/java/org/apache/cxf/common/util/ rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/ rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/securit...
Date Thu, 30 Jan 2014 17:34:44 GMT
Author: sergeyb
Date: Thu Jan 30 17:34:44 2014
New Revision: 1562902

URL: http://svn.apache.org/r1562902
Log:
[CXF-5513] Optional compression before the encryption, initial support for encryption/decryption
with certificates

Added:
    cxf/trunk/core/src/main/java/org/apache/cxf/common/util/CompressionUtils.java   (with
props)
Modified:
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthServiceException.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtils.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/SecretKeyProperties.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptingDataProvider.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java
    cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/DeflateEncoderDecoder.java

Added: cxf/trunk/core/src/main/java/org/apache/cxf/common/util/CompressionUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/core/src/main/java/org/apache/cxf/common/util/CompressionUtils.java?rev=1562902&view=auto
==============================================================================
--- cxf/trunk/core/src/main/java/org/apache/cxf/common/util/CompressionUtils.java (added)
+++ cxf/trunk/core/src/main/java/org/apache/cxf/common/util/CompressionUtils.java Thu Jan
30 17:34:44 2014
@@ -0,0 +1,88 @@
+/**
+ * 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.common.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+public final class CompressionUtils {
+    private CompressionUtils() {
+        
+    }
+    public static InputStream decompress(byte[] deflatedToken) 
+        throws DataFormatException {
+        return decompress(deflatedToken, true);
+    }
+    public static InputStream decompress(byte[] deflatedToken, boolean nowrap) 
+        throws DataFormatException {
+        Inflater inflater = new Inflater(nowrap);
+        inflater.setInput(deflatedToken);
+        
+        byte[] input = new byte[deflatedToken.length * 2];
+        int inflatedLen = 0;
+        int inputLen = 0;
+        byte[] inflatedToken = input;
+        while (!inflater.finished()) {
+            inputLen = inflater.inflate(input);
+            if (!inflater.finished()) {
+                
+                if (inputLen == 0) {
+                    if (inflater.needsInput()) {
+                        throw new DataFormatException("Inflater can not inflate all the token
bytes");
+                    } else {
+                        break;
+                    }
+                }
+                
+                inflatedToken = new byte[input.length + inflatedLen];
+                System.arraycopy(input, 0, inflatedToken, inflatedLen, inputLen);
+                inflatedLen += inputLen;
+            }
+        }
+        InputStream is = new ByteArrayInputStream(input, 0, inputLen);
+        if (inflatedToken != input) {
+            is = new SequenceInputStream(new ByteArrayInputStream(inflatedToken, 0, inflatedLen),
+                                         is);
+        }
+        return is;
+    }
+    
+    public static byte[] compress(byte[] tokenBytes) {
+        return compress(tokenBytes, true);
+    }
+    
+    public static byte[] compress(byte[] tokenBytes, boolean nowrap) {
+        Deflater compresser = new Deflater(Deflater.DEFLATED, nowrap);
+        
+        compresser.setInput(tokenBytes);
+        compresser.finish();
+        
+        byte[] output = new byte[tokenBytes.length * 2];
+        
+        int compressedDataLength = compresser.deflate(output);
+        
+        byte[] result = new byte[compressedDataLength];
+        System.arraycopy(output, 0, result, 0, compressedDataLength);
+        return result;
+    }
+}

Propchange: cxf/trunk/core/src/main/java/org/apache/cxf/common/util/CompressionUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/core/src/main/java/org/apache/cxf/common/util/CompressionUtils.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthServiceException.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthServiceException.java?rev=1562902&r1=1562901&r2=1562902&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthServiceException.java
(original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthServiceException.java
Thu Jan 30 17:34:44 2014
@@ -31,6 +31,10 @@ public class OAuthServiceException exten
     private static final long serialVersionUID = 343738539234766320L;
     private OAuthError error;
     
+    public OAuthServiceException() {
+        super(OAuthConstants.SERVER_ERROR);
+    }
+    
     public OAuthServiceException(String message) {
         super(message);
     }

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtils.java?rev=1562902&r1=1562901&r2=1562902&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtils.java
(original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtils.java
Thu Jan 30 17:34:44 2014
@@ -20,6 +20,7 @@
 package org.apache.cxf.rs.security.oauth2.utils;
 
 import java.security.Key;
+import java.security.PublicKey;
 import java.security.SecureRandom;
 import java.security.spec.AlgorithmParameterSpec;
 
@@ -28,6 +29,8 @@ import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
 
+import org.apache.cxf.common.util.CompressionUtils;
+import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
 
 
@@ -125,8 +128,14 @@ public final class EncryptionUtils {
         }
     }
     
-    public static byte[] processBytes(byte[] bytes, Key secretKey, 
-                                      SecretKeyProperties keyProps, int mode) {
+    public static byte[] processBytes(byte[] bytes, 
+                                      Key secretKey, 
+                                      SecretKeyProperties keyProps, 
+                                      int mode) {
+        boolean compressionSupported = keyProps != null && keyProps.isCompressionSupported();
+        if (compressionSupported && mode == Cipher.ENCRYPT_MODE) {
+            bytes = CompressionUtils.compress(bytes, false);
+        }
         try {
             Cipher c = Cipher.getInstance(secretKey.getAlgorithm());
             if (keyProps == null || keyProps.getAlgoSpec() == null && keyProps.getSecureRandom()
== null) {
@@ -142,12 +151,38 @@ public final class EncryptionUtils {
                     c.init(mode, secretKey, algoSpec, random);
                 }
             }
-            return c.doFinal(bytes);
+            byte[] result = new byte[0];
+            int blockSize = keyProps != null ? keyProps.getBlockSize() : -1;
+            if (secretKey instanceof SecretKey && blockSize == -1) {
+                result = c.doFinal(bytes);
+            } else {
+                if (blockSize == -1) {
+                    blockSize = secretKey instanceof PublicKey ? 117 : 128;
+                }
+                int offset = 0;
+                for (; offset + blockSize < bytes.length; offset += blockSize) {
+                    result = addToResult(result, c.doFinal(bytes, offset, blockSize));
+                }
+                if (offset < bytes.length) {
+                    result = addToResult(result, c.doFinal(bytes, offset, bytes.length -
offset));
+                }
+            }
+            if (compressionSupported && mode == Cipher.DECRYPT_MODE) {
+                result = IOUtils.readBytesFromStream(CompressionUtils.decompress(result,
false));
+            }
+            return result;
         } catch (Exception ex) {
             throw new OAuthServiceException(ex);
         }
     }
     
+    private static byte[] addToResult(byte[] prefix, byte[] suffix) {
+        byte[] result = new byte[prefix.length + suffix.length];
+        System.arraycopy(prefix, 0, result, 0, prefix.length);
+        System.arraycopy(suffix, 0, result, prefix.length, suffix.length);
+        return result;
+    }
+    
     public static SecretKey decodeSecretKey(String encodedSecretKey, String algo) {
         try {
             byte[] secretKeyBytes = decodeSequence(encodedSecretKey);

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/SecretKeyProperties.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/SecretKeyProperties.java?rev=1562902&r1=1562901&r2=1562902&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/SecretKeyProperties.java
(original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/SecretKeyProperties.java
Thu Jan 30 17:34:44 2014
@@ -24,8 +24,10 @@ import java.security.spec.AlgorithmParam
 public class SecretKeyProperties {
     private String keyAlgo;
     private int keySize;
+    private int blockSize = -1;
     private SecureRandom secureRandom;
     private AlgorithmParameterSpec algoSpec;
+    private boolean compressionSupported = true;
     public SecretKeyProperties() {
         this("AES", 128);
     }
@@ -60,6 +62,19 @@ public class SecretKeyProperties {
     public void setAlgoSpec(AlgorithmParameterSpec algoSpec) {
         this.algoSpec = algoSpec;
     }
+    public int getBlockSize() {
+        return blockSize;
+    }
+    public void setBlockSize(int blockSize) {
+        this.blockSize = blockSize;
+    }
+    public boolean isCompressionSupported() {
+        return compressionSupported;
+    }
+    public void setCompressionSupported(boolean compressionSupported) {
+        this.compressionSupported = compressionSupported;
+    }
+    
     
     
 }

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptingDataProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptingDataProvider.java?rev=1562902&r1=1562901&r2=1562902&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptingDataProvider.java
(original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptingDataProvider.java
Thu Jan 30 17:34:44 2014
@@ -100,14 +100,18 @@ public class EncryptingDataProvider impl
     }
 
     @Override
-    public ServerAccessToken getPreauthorizedToken(Client client, List<String> requestedScopes,
-                                                   UserSubject subject, String grantType)
-        throws OAuthServiceException {
-        return null;
+    public List<OAuthPermission> convertScopeToPermissions(Client client, List<String>
requestedScope) {
+        // assuming that no specific scopes is documented/supported
+        return Collections.emptyList();
     }
     
     @Override
-    public List<OAuthPermission> convertScopeToPermissions(Client client, List<String>
requestedScope) {
+    public ServerAccessToken getPreauthorizedToken(Client client, List<String> requestedScopes,
+                                                   UserSubject subject, String grantType)
+        throws OAuthServiceException {
+        // This is an optimization useful in cases where a client requests an authorization
code: 
+        // if a user has already provided a given client with a pre-authorized token then
challenging 
+        // a user with yet another form asking for the authorization is redundant  
         return null;
     }
     

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java?rev=1562902&r1=1562901&r2=1562902&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java
(original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java
Thu Jan 30 17:34:44 2014
@@ -21,6 +21,10 @@ package org.apache.cxf.rs.security.oauth
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.lang.annotation.Annotation;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
 import java.util.Collections;
 import java.util.List;
 
@@ -63,7 +67,6 @@ public class EncryptionUtilsTest extends
         
         // encrypt
         ServerAccessToken token = p.createAccessToken(atr);
-        // decrypt
         ServerAccessToken token2 = p.getAccessToken(token.getTokenKey());
         
         // compare tokens
@@ -105,6 +108,37 @@ public class EncryptionUtilsTest extends
     }
     
     @Test
+    public void testBearerTokenJSONCertificate() throws Exception {
+        
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+        KeyPair keyPair = kpg.generateKeyPair();
+        PublicKey publicKey = keyPair.getPublic();
+        PrivateKey privateKey = keyPair.getPrivate();
+        
+        AccessTokenRegistration atr = prepareTokenRegistration();
+        
+        BearerAccessToken token = p.createAccessTokenInternal(atr);
+        JSONProvider<BearerAccessToken> jsonp = new JSONProvider<BearerAccessToken>();
+        jsonp.setMarshallAsJaxbElement(true);
+        jsonp.setUnmarshallAsJaxbElement(true);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        jsonp.writeTo(token, BearerAccessToken.class, new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE,
+                      new MetadataMap<String, Object>(), bos);
+        
+        SecretKeyProperties props1 = new SecretKeyProperties(publicKey.getAlgorithm());
+        String encrypted = EncryptionUtils.encryptSequence(bos.toString(), publicKey, props1);
+        SecretKeyProperties props2 = new SecretKeyProperties(privateKey.getAlgorithm());
+        String decrypted = EncryptionUtils.decryptSequence(encrypted, privateKey, props2);
+        ServerAccessToken token2 = jsonp.readFrom(BearerAccessToken.class, BearerAccessToken.class,

+                                                  new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE,

+                                                  new MetadataMap<String, String>(),

+                                                  new ByteArrayInputStream(decrypted.getBytes()));
+        
+        // compare tokens
+        compareAccessTokens(token, token2);
+    }
+    
+    @Test
     public void testClientJSON() throws Exception {
         Client c = new Client("client", "secret", true);
         c.setSubject(new UserSubject("subject", "id"));
@@ -199,5 +233,20 @@ public class EncryptionUtilsTest extends
         return atr;
     }
     
-    
+// TODO: remove once the wiki documentation is updated
+//  KeyStore keyStore = loadKeyStore(); 
+//  Certificate cert = keyStore.getCertificate("alice");
+//  PublicKey publicKey = cert.getPublicKey();
+//  KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
+//      keyStore.getEntry("alice", new KeyStore.PasswordProtection(
+//           new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}));
+//  PrivateKey privateKey = pkEntry.getPrivateKey();
+    
+    
+//    private KeyStore loadKeyStore() throws Exception {
+//        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+//        InputStream is = this.getClass().getResourceAsStream("alice.jks");
+//        ks.load(is, new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'});
+//        return ks;
+//    }
 }

Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/DeflateEncoderDecoder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/DeflateEncoderDecoder.java?rev=1562902&r1=1562901&r2=1562902&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/DeflateEncoderDecoder.java
(original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/DeflateEncoderDecoder.java
Thu Jan 30 17:34:44 2014
@@ -18,60 +18,18 @@
  */
 package org.apache.cxf.rs.security.saml;
 
-import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.io.SequenceInputStream;
 import java.util.zip.DataFormatException;
-import java.util.zip.Deflater;
-import java.util.zip.Inflater;
+
+import org.apache.cxf.common.util.CompressionUtils;
 
 public class DeflateEncoderDecoder {
     public InputStream inflateToken(byte[] deflatedToken) 
         throws DataFormatException {
-        Inflater inflater = new Inflater(true);
-        inflater.setInput(deflatedToken);
-        
-        byte[] input = new byte[deflatedToken.length * 2];
-        int inflatedLen = 0;
-        int inputLen = 0;
-        byte[] inflatedToken = input;
-        while (!inflater.finished()) {
-            inputLen = inflater.inflate(input);
-            if (!inflater.finished()) {
-                
-                if (inputLen == 0) {
-                    if (inflater.needsInput()) {
-                        throw new DataFormatException("Inflater can not inflate all the token
bytes");
-                    } else {
-                        break;
-                    }
-                }
-                
-                inflatedToken = new byte[input.length + inflatedLen];
-                System.arraycopy(input, 0, inflatedToken, inflatedLen, inputLen);
-                inflatedLen += inputLen;
-            }
-        }
-        InputStream is = new ByteArrayInputStream(input, 0, inputLen);
-        if (inflatedToken != input) {
-            is = new SequenceInputStream(new ByteArrayInputStream(inflatedToken, 0, inflatedLen),
-                                         is);
-        }
-        return is;
+        return CompressionUtils.decompress(deflatedToken);
     }
     
     public byte[] deflateToken(byte[] tokenBytes) {
-        Deflater compresser = new Deflater(Deflater.DEFLATED, true);
-        
-        compresser.setInput(tokenBytes);
-        compresser.finish();
-        
-        byte[] output = new byte[tokenBytes.length * 2];
-        
-        int compressedDataLength = compresser.deflate(output);
-        
-        byte[] result = new byte[compressedDataLength];
-        System.arraycopy(output, 0, result, 0, compressedDataLength);
-        return result;
+        return CompressionUtils.compress(tokenBytes);
     }
 }



Mime
View raw message