1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright  2003-2004 The Apache Software Foundation.
   7  *
   8  *  Licensed under the Apache License, Version 2.0 (the "License");
   9  *  you may not use this file except in compliance with the License.
  10  *  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  *  Unless required by applicable law or agreed to in writing, software
  15  *  distributed under the License is distributed on an "AS IS" BASIS,
  16  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  *  See the License for the specific language governing permissions and
  18  *  limitations under the License.
  19  *
  20  */
  21 
  22 package com.sun.org.apache.xml.internal.security.encryption;
  23 
  24 import java.io.IOException;
  25 
  26 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
  27 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;
  28 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException;
  29 import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
  30 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
  31 import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
  32 import org.w3c.dom.Attr;
  33 import com.sun.org.apache.xml.internal.security.utils.Base64;
  34 
  35 
  36 /**
  37  * <code>XMLCipherInput</code> is used to wrap input passed into the
  38  * XMLCipher encryption operations.
  39  *
  40  * In decryption mode, it takes a <code>CipherData</code> object and allows
  41  * callers to dereference the CipherData into the encrypted bytes that it
  42  * actually represents.  This takes care of all base64 encoding etc.
  43  *
  44  * While primarily an internal class, this can be used by applications to
  45  * quickly and easily retrieve the encrypted bytes from an EncryptedType
  46  * object
  47  *
  48  * @author Berin Lautenbach
  49  */
  50 public class XMLCipherInput {
  51 
  52     private static java.util.logging.Logger logger =
  53         java.util.logging.Logger.getLogger(XMLCipher.class.getName());
  54 
  55         /** The data we are working with */
  56         private CipherData _cipherData;
  57 
  58         /** MODES */
  59         private int _mode;
  60 
  61         /**
  62          * Constructor for processing encrypted octets
  63          *
  64          * @param data The <code>CipherData</code> object to read the bytes from
  65          * @throws XMLEncryptionException {@link XMLEncryptionException}
  66          */
  67 
  68         public XMLCipherInput(CipherData data) throws XMLEncryptionException {
  69 
  70                 _cipherData = data;
  71                 _mode = XMLCipher.DECRYPT_MODE;
  72                 if (_cipherData == null) {
  73                         throw new XMLEncryptionException("CipherData is null");
  74                 }
  75 
  76         }
  77 
  78         /**
  79          * Constructor for processing encrypted octets
  80          *
  81          * @param input The <code>EncryptedType</code> object to read
  82          * the bytes from.
  83          * @throws XMLEncryptionException {@link XMLEncryptionException}
  84          */
  85 
  86         public XMLCipherInput(EncryptedType input) throws XMLEncryptionException {
  87 
  88                 _cipherData = ((input == null) ? null : input.getCipherData());
  89                 _mode = XMLCipher.DECRYPT_MODE;
  90                 if (_cipherData == null) {
  91                         throw new XMLEncryptionException("CipherData is null");
  92                 }
  93 
  94         }
  95 
  96         /**
  97          * Dereferences the input and returns it as a single byte array.
  98          *
  99          * @throws XMLEncryptionException
 100      * @return The decripted bytes.
 101          */
 102 
 103         public byte[] getBytes() throws XMLEncryptionException {
 104 
 105                 if (_mode == XMLCipher.DECRYPT_MODE) {
 106                         return getDecryptBytes();
 107                 }
 108                 return null;
 109         }
 110 
 111     /**
 112      * Internal method to get bytes in decryption mode
 113      * @return the decripted bytes
 114      * @throws XMLEncryptionException
 115      */
 116     private byte[] getDecryptBytes() throws XMLEncryptionException {
 117 
 118         String base64EncodedEncryptedOctets = null;
 119 
 120         if (_cipherData.getDataType() == CipherData.REFERENCE_TYPE) {
 121             // Fun time!
 122             logger.log(java.util.logging.Level.FINE, "Found a reference type CipherData");
 123             CipherReference cr = _cipherData.getCipherReference();
 124 
 125             // Need to wrap the uri in an Attribute node so that we can
 126             // Pass to the resource resolvers
 127 
 128             Attr uriAttr = cr.getURIAsAttr();
 129             XMLSignatureInput input = null;
 130 
 131             try {
 132                 ResourceResolver resolver =
 133                     ResourceResolver.getInstance(uriAttr, null);
 134                 input = resolver.resolve(uriAttr, null);
 135             } catch (ResourceResolverException ex) {
 136                 throw new XMLEncryptionException("empty", ex);
 137             }
 138 
 139             if (input != null) {
 140                 logger.log(java.util.logging.Level.FINE, "Managed to resolve URI \"" + cr.getURI() + "\"");
 141             } else {
 142                 logger.log(java.util.logging.Level.FINE, "Failed to resolve URI \"" + cr.getURI() + "\"");
 143             }
 144 
 145             // Lets see if there are any transforms
 146             Transforms transforms = cr.getTransforms();
 147             if (transforms != null) {
 148                 logger.log(java.util.logging.Level.FINE, "Have transforms in cipher reference");
 149                 try {
 150                     com.sun.org.apache.xml.internal.security.transforms.Transforms dsTransforms =
 151                         transforms.getDSTransforms();
 152                     input = dsTransforms.performTransforms(input);
 153                 } catch (TransformationException ex) {
 154                     throw new XMLEncryptionException("empty", ex);
 155                 }
 156             }
 157 
 158             try {
 159                 return input.getBytes();
 160             } catch (IOException ex) {
 161                 throw new XMLEncryptionException("empty", ex);
 162             } catch (CanonicalizationException ex) {
 163                 throw new XMLEncryptionException("empty", ex);
 164             }
 165 
 166         // retrieve the cipher text
 167         } else if (_cipherData.getDataType() == CipherData.VALUE_TYPE) {
 168             base64EncodedEncryptedOctets =
 169                 _cipherData.getCipherValue().getValue();
 170         } else {
 171             throw new XMLEncryptionException("CipherData.getDataType() returned unexpected value");
 172         }
 173 
 174         logger.log(java.util.logging.Level.FINE, "Encrypted octets:\n" + base64EncodedEncryptedOctets);
 175 
 176         byte[] encryptedBytes = null;
 177         try {
 178             encryptedBytes = Base64.decode(base64EncodedEncryptedOctets);
 179         } catch (Base64DecodingException bde) {
 180             throw new XMLEncryptionException("empty", bde);
 181         }
 182 
 183         return (encryptedBytes);
 184     }
 185 }