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 }