001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: EncryptedNameIdentifier.java,v 1.4 2008/06/25 05:46:46 qcheng Exp $ 026 * 027 */ 028 029package com.sun.identity.federation.message.common; 030 031import java.security.Key; 032import java.security.PrivateKey; 033import org.w3c.dom.Document; 034import org.w3c.dom.Element; 035import org.w3c.dom.Node; 036import com.sun.identity.federation.common.FSException; 037import com.sun.identity.federation.common.FSUtils; 038import com.sun.identity.federation.common.IFSConstants; 039import com.sun.identity.federation.jaxb.entityconfig.BaseConfigType; 040import com.sun.identity.federation.key.EncInfo; 041import com.sun.identity.federation.key.KeyUtil; 042import com.sun.identity.federation.meta.IDFFMetaException; 043import com.sun.identity.federation.meta.IDFFMetaManager; 044import com.sun.identity.federation.meta.IDFFMetaUtils; 045import com.sun.identity.federation.services.util.FSServiceUtils; 046import com.sun.identity.liberty.ws.meta.jaxb.ProviderDescriptorType; 047import com.sun.identity.shared.xml.XMLUtils; 048import com.sun.identity.shared.encode.Base64; 049import com.sun.identity.xmlenc.XMLEncryptionManager; 050import com.sun.identity.xmlenc.EncryptionException; 051import com.sun.identity.saml.assertion.NameIdentifier; 052import com.sun.identity.saml.common.SAMLUtils; 053import com.sun.identity.saml.common.SAMLException; 054 055/** 056 * This class <code>EncryptedNameIdentifier</code> represents a 057 * <code>EncryptableNameIdentifier</code> in an encrypted form. 058 * 059 * @supported.all.api 060 */ 061public class EncryptedNameIdentifier { 062 063 /** 064 * Returns the encryptable XML document element. 065 * 066 * @param eni the <code>EncrytableNameIdentifier</code> object. 067 * 068 * @return the <code>EncryptedNameIdentifier</code> XML Document. 069 */ 070 private static Document getEncryptableDocument( 071 EncryptableNameIdentifier eni) { 072 073 StringBuffer xml = new StringBuffer(300); 074 String NS = IFSConstants.LIB_12_NAMESPACE_STRING; 075 String appendNS = IFSConstants.LIB_PREFIX; 076 077 xml.append("<").append(appendNS).append("EncryptedNameIdentifier") 078 .append(" ").append(NS).append(">").append(eni.toString()) 079 .append("</").append(appendNS) 080 .append("EncryptedNameIdentifier").append(">"); 081 if(FSUtils.debug.messageEnabled()) { 082 FSUtils.debug.message("EncryptedNameIdentifier.getEncryptable" + 083 "NameIdentifier: doc =" + xml.toString()); 084 } 085 return XMLUtils.toDOMDocument(xml.toString(), FSUtils.debug); 086 087 } 088 089 090 /** 091 * Returns the <code>EncryptedNameIdentifier</code> for a given name 092 * identifier and the provider ID. 093 * 094 * @param ni the <code>NameIdentifier</code> object. 095 * @param realm The realm under which the entity resides. 096 * @param providerID the remote provider identifier. 097 * @return the <code>NameIdentifier</code> object. 098 * @throws FSException on error. 099 */ 100 public static NameIdentifier getEncryptedNameIdentifier( 101 NameIdentifier ni, String realm, String providerID) 102 throws FSException { 103 104 if(ni == null || providerID == null) { 105 FSUtils.debug.error("EncryptedNameIdentifier.construct: " + 106 "nullInputParameter"); 107 throw new FSException("nullInputParameter", null); 108 } 109 ProviderDescriptorType providerDesc = null; 110 try { 111 IDFFMetaManager metaManager = FSUtils.getIDFFMetaManager(); 112 if (metaManager != null) { 113 providerDesc = metaManager.getSPDescriptor(realm, providerID); 114 115 if (providerDesc == null) { 116 providerDesc = metaManager.getIDPDescriptor( 117 realm, providerID); 118 } 119 } 120 if (providerDesc == null) { 121 throw new IDFFMetaException((String) null); 122 } 123 } catch (IDFFMetaException ae) { 124 FSUtils.debug.error("EncryptedNameIdentifier.construct: Could" + 125 "not retrieve the meta for provider" + providerID); 126 throw new FSException(ae); 127 } 128 129 EncInfo encInfo = KeyUtil.getEncInfo(providerDesc, providerID, false); 130 return getEncryptedNameIdentifier(ni, providerID, 131 encInfo.getWrappingKey(), encInfo.getDataEncAlgorithm(), 132 encInfo.getDataEncStrength()); 133 } 134 135 /** 136 * Gets then Encrypted NameIdentifier for a given name identifier 137 * and the provider ID. 138 * @param ni NameIdentifier. 139 * @param providerID Remote Provider ID. 140 * @param enckey Key Encryption Key 141 * @param dataEncAlgorithm Data encryption algorithm 142 * @param dataEncStrength Data encryption key size 143 * 144 * @return NameIdentifier EncryptedNameIdentifier. 145 * @exception FSException for failure. 146 */ 147 public static NameIdentifier getEncryptedNameIdentifier( 148 NameIdentifier ni, String providerID, Key enckey, 149 String dataEncAlgorithm, int dataEncStrength) throws FSException { 150 151 if(ni == null || providerID == null) { 152 FSUtils.debug.error("EncryptedNameIdentifier.construct: " + 153 "nullInputParameter"); 154 throw new FSException("nullInputParameter", null); 155 } 156 157 EncryptableNameIdentifier eni = new EncryptableNameIdentifier(ni); 158 Document encryptableDoc = getEncryptableDocument(eni); 159 Document encryptedDoc = null; 160 161 try { 162 Element encryptElement = (Element)encryptableDoc. 163 getElementsByTagNameNS(IFSConstants.FF_12_XML_NS, 164 "EncryptableNameIdentifier").item(0); 165 166 167 XMLEncryptionManager manager = XMLEncryptionManager.getInstance(); 168 encryptedDoc = manager.encryptAndReplace( 169 encryptableDoc, 170 encryptElement, 171 dataEncAlgorithm, 172 dataEncStrength, 173 enckey, 174 0, // TODO: should we pick it up from extended meta? 175 providerID); 176 177 } catch (EncryptionException ee) { 178 FSUtils.debug.error("EncryptedNameIdentifier.construct: Unable" + 179 "to encrypt the xml doc", ee); 180 throw new FSException(ee); 181 } 182 183 if(encryptedDoc == null) { 184 throw new FSException("EncryptionFailed", null); 185 } 186 187 String encodedStr = Base64.encode( 188 SAMLUtils.stringToByteArray( 189 XMLUtils.print((Node)(encryptedDoc)))); 190 191 try { 192 return new NameIdentifier(encodedStr, ni.getNameQualifier(), 193 IFSConstants.NI_ENCRYPTED_FORMAT_URI); 194 195 } catch(SAMLException se) { 196 throw new FSException(se); 197 } 198 199 } 200 201 /** 202 * Returns the decrypted <code>NameIdentifier</code> object. 203 * 204 * @param encNI the <code>EncryptedNameIdentifier</code> object. 205 * @param realm The realm under which the entity resides. 206 * @param providerID the Hosted Provider Identifer. 207 * @return the <code>NameIdentifier</code> object, 208 * the decrypted <code>NameIdentifier</code>. 209 * @throws FSException on error. 210 */ 211 public static NameIdentifier getDecryptedNameIdentifier( 212 NameIdentifier encNI, String realm, String providerID) 213 throws FSException 214 { 215 216 if(encNI == null || providerID == null) { 217 FSUtils.debug.error("EncryptedNameIdentifier.getDecryptedName" + 218 "Identifier: null values"); 219 throw new FSException("nullInputParameter", null); 220 } 221 222 BaseConfigType providerConfig = null; 223 try { 224 providerConfig = FSUtils.getIDFFMetaManager(). 225 getSPDescriptorConfig(realm, providerID); 226 if (providerConfig == null) { 227 providerConfig = FSUtils.getIDFFMetaManager(). 228 getIDPDescriptorConfig(realm, providerID); 229 } 230 } catch (Exception ae) { 231 FSUtils.debug.error("EncryptedNameIdentifier.getDecryptedName" + 232 "Identifier: Unable to find provider", ae); 233 throw new FSException(ae); 234 } 235 236 if (providerConfig == null) { 237 FSUtils.debug.error("EncryptedNameIdentifier.getDecryptedName" + 238 "Identifier: Unable to find provider " + providerID); 239 throw new FSException("noProviderFound", null); 240 } 241 242 return getDecryptedNameIdentifier(encNI, 243 KeyUtil.getDecryptionKey(providerConfig)); 244 } 245 246 /** 247 * Gets the decrypted NameIdentifier. 248 * @param encNI EncryptedNameIdentifier. 249 * @param decKey decryption key. 250 * 251 * @return NameIdentifier Decrypted NameIdentifier. 252 * @exception FSException for failures 253 */ 254 public static NameIdentifier getDecryptedNameIdentifier( 255 NameIdentifier encNI, PrivateKey decKey) throws FSException { 256 257 258 if(encNI.getFormat() == null || 259 !encNI.getFormat().equals( 260 IFSConstants.NI_ENCRYPTED_FORMAT_URI)) { 261 throw new FSException("notValidFormat", null); 262 } 263 264 String name = encNI.getName(); 265 name = FSUtils.removeNewLineChars(name); 266 String decodeStr = SAMLUtils.byteArrayToString(Base64.decode(name)); 267 268 Document encryptedDoc = 269 XMLUtils.toDOMDocument(decodeStr, FSUtils.debug); 270 271 try { 272 XMLEncryptionManager manager = XMLEncryptionManager.getInstance(); 273 Document doc = manager.decryptAndReplace(encryptedDoc, decKey); 274 275 Element element = (Element)doc.getElementsByTagNameNS( 276 IFSConstants.FF_12_XML_NS, 277 "EncryptableNameIdentifier").item(0); 278 279 EncryptableNameIdentifier eni = 280 new EncryptableNameIdentifier(element); 281 return new NameIdentifier(eni.getName(), eni.getNameQualifier(), 282 eni.getFormat()); 283 284 } catch (EncryptionException ee) { 285 FSUtils.debug.error("EncryptedNameIdentifier.getDecryptedName" + 286 "Identifier: Decryption exception", ee); 287 throw new FSException(ee); 288 } catch (SAMLException se) { 289 throw new FSException(se); 290 } 291 292 } 293}