| 1 17 package com.sun.org.apache.xml.internal.security.encryption; 18 19 20 import java.io.ByteArrayOutputStream ; 21 import java.io.IOException ; 22 import java.io.StringReader ; 23 import java.io.UnsupportedEncodingException ; 24 import java.security.InvalidAlgorithmParameterException ; 25 import java.security.InvalidKeyException ; 26 import java.security.Key ; 27 import java.security.NoSuchAlgorithmException ; 28 import java.security.NoSuchProviderException ; 29 import java.util.Iterator ; 30 import java.util.LinkedList ; 31 import java.util.List ; 32 33 import javax.crypto.BadPaddingException; 34 import javax.crypto.Cipher; 35 import javax.crypto.IllegalBlockSizeException; 36 import javax.crypto.NoSuchPaddingException; 37 import javax.crypto.spec.IvParameterSpec; 38 import javax.xml.parsers.DocumentBuilder ; 39 import javax.xml.parsers.DocumentBuilderFactory ; 40 import javax.xml.parsers.ParserConfigurationException ; 41 42 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper; 43 import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm; 44 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; 45 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException; 46 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; 47 import com.sun.org.apache.xml.internal.security.keys.KeyInfo; 48 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException; 49 import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.EncryptedKeyResolver; 50 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; 51 import com.sun.org.apache.xml.internal.security.transforms.InvalidTransformException; 52 import com.sun.org.apache.xml.internal.security.transforms.TransformationException; 53 import com.sun.org.apache.xml.internal.security.utils.Base64; 54 import com.sun.org.apache.xml.internal.security.utils.Constants; 55 import com.sun.org.apache.xml.internal.security.utils.ElementProxy; 56 import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants; 57 import com.sun.org.apache.xml.internal.security.utils.XMLUtils; 58 import com.sun.org.apache.xml.internal.utils.URI; 59 import org.w3c.dom.Attr ; 60 import org.w3c.dom.Document ; 61 import org.w3c.dom.DocumentFragment ; 62 import org.w3c.dom.Element ; 63 import org.w3c.dom.NamedNodeMap ; 64 import org.w3c.dom.Node ; 65 import org.w3c.dom.NodeList ; 66 import org.xml.sax.InputSource ; 67 import org.xml.sax.SAXException ; 68 69 70 79 public class XMLCipher { 80 81 private static java.util.logging.Logger logger = 82 java.util.logging.Logger.getLogger(XMLCipher.class.getName()); 83 84 86 public static final String TRIPLEDES = 87 EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES; 88 89 public static final String AES_128 = 90 EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128; 91 92 public static final String AES_256 = 93 EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256; 94 95 public static final String AES_192 = 96 EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192; 97 98 public static final String RSA_v1dot5 = 99 EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15; 100 101 public static final String RSA_OAEP = 102 EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP; 103 104 public static final String DIFFIE_HELLMAN = 105 EncryptionConstants.ALGO_ID_KEYAGREEMENT_DH; 106 107 public static final String TRIPLEDES_KeyWrap = 108 EncryptionConstants.ALGO_ID_KEYWRAP_TRIPLEDES; 109 110 public static final String AES_128_KeyWrap = 111 EncryptionConstants.ALGO_ID_KEYWRAP_AES128; 112 113 public static final String AES_256_KeyWrap = 114 EncryptionConstants.ALGO_ID_KEYWRAP_AES256; 115 116 public static final String AES_192_KeyWrap = 117 EncryptionConstants.ALGO_ID_KEYWRAP_AES192; 118 119 public static final String SHA1 = 120 Constants.ALGO_ID_DIGEST_SHA1; 121 122 public static final String SHA256 = 123 MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256; 124 125 public static final String SHA512 = 126 MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA512; 127 128 public static final String RIPEMD_160 = 129 MessageDigestAlgorithm.ALGO_ID_DIGEST_RIPEMD160; 130 131 public static final String XML_DSIG = 132 Constants.SignatureSpecNS; 133 134 public static final String N14C_XML = 135 Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS; 136 137 public static final String N14C_XML_WITH_COMMENTS = 138 Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS; 139 140 public static final String EXCL_XML_N14C = 141 Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS; 142 143 public static final String EXCL_XML_N14C_WITH_COMMENTS = 144 Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS; 145 146 public static final String BASE64_ENCODING = 147 com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_BASE64_DECODE; 148 150 151 public static final int ENCRYPT_MODE = Cipher.ENCRYPT_MODE; 152 153 public static final int DECRYPT_MODE = Cipher.DECRYPT_MODE; 154 155 public static final int UNWRAP_MODE = Cipher.UNWRAP_MODE; 156 157 public static final int WRAP_MODE = Cipher.WRAP_MODE; 158 159 private static final String ENC_ALGORITHMS = TRIPLEDES + "\n" + 160 AES_128 + "\n" + AES_256 + "\n" + AES_192 + "\n" + RSA_v1dot5 + "\n" + 161 RSA_OAEP + "\n" + TRIPLEDES_KeyWrap + "\n" + AES_128_KeyWrap + "\n" + 162 AES_256_KeyWrap + "\n" + AES_192_KeyWrap+ "\n"; 163 164 165 private Cipher _contextCipher; 166 167 private int _cipherMode = Integer.MIN_VALUE; 168 169 private String _algorithm = null; 170 171 private String _requestedJCEProvider = null; 172 173 private Canonicalizer _canon; 174 175 private Document _contextDocument; 176 177 private Factory _factory; 178 179 private Serializer _serializer; 180 181 182 private Key _key; 183 185 private Key _kek; 186 187 190 private EncryptedKey _ek; 191 192 195 private EncryptedData _ed; 196 197 202 private XMLCipher() { 203 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Constructing XMLCipher..."); 204 205 _factory = new Factory (); 206 _serializer = new Serializer(); 207 208 } 209 210 217 private static boolean isValidEncryptionAlgorithm(String algorithm) { 218 boolean result = ( 219 algorithm.equals(TRIPLEDES) || 220 algorithm.equals(AES_128) || 221 algorithm.equals(AES_256) || 222 algorithm.equals(AES_192) || 223 algorithm.equals(RSA_v1dot5) || 224 algorithm.equals(RSA_OAEP) || 225 algorithm.equals(TRIPLEDES_KeyWrap) || 226 algorithm.equals(AES_128_KeyWrap) || 227 algorithm.equals(AES_256_KeyWrap) || 228 algorithm.equals(AES_192_KeyWrap) 229 ); 230 231 return (result); 232 } 233 234 262 public static XMLCipher getInstance(String transformation) throws 263 XMLEncryptionException { 264 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher..."); 266 if (null == transformation) 267 logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null..."); 268 if(!isValidEncryptionAlgorithm(transformation)) 269 logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS); 270 271 XMLCipher instance = new XMLCipher(); 272 273 instance._algorithm = transformation; 274 instance._key = null; 275 instance._kek = null; 276 277 278 280 281 try { 282 instance._canon = Canonicalizer.getInstance 283 (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS); 284 285 } catch (InvalidCanonicalizerException ice) { 286 throw new XMLEncryptionException("empty", ice); 287 } 288 289 String jceAlgorithm = JCEMapper.translateURItoJCEID(transformation); 290 291 try { 292 instance._contextCipher = Cipher.getInstance(jceAlgorithm); 293 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " + 294 instance._contextCipher.getAlgorithm()); 295 } catch (NoSuchAlgorithmException nsae) { 296 throw new XMLEncryptionException("empty", nsae); 297 } catch (NoSuchPaddingException nspe) { 298 throw new XMLEncryptionException("empty", nspe); 299 } 300 301 return (instance); 302 } 303 304 public static XMLCipher getInstance(String transformation,Cipher cipher) throws 305 XMLEncryptionException { 306 logger.log(java.util.logging.Level.FINE, "Getting XMLCipher..."); 308 if (null == transformation) 309 logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null..."); 310 if(!isValidEncryptionAlgorithm(transformation)) 311 logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS); 312 313 XMLCipher instance = new XMLCipher(); 314 315 instance._algorithm = transformation; 316 instance._key = null; 317 instance._kek = null; 318 319 320 322 323 try { 324 instance._canon = Canonicalizer.getInstance 325 (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS); 326 327 } catch (InvalidCanonicalizerException ice) { 328 throw new XMLEncryptionException("empty", ice); 329 } 330 331 String jceAlgorithm = JCEMapper.translateURItoJCEID(transformation); 332 333 try { 334 instance._contextCipher = cipher; 335 logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " + 337 instance._contextCipher.getAlgorithm()); 338 }catch(Exception ex) { 339 throw new XMLEncryptionException("empty", ex); 340 } 341 342 return (instance); 343 } 344 345 346 347 363 364 public static XMLCipher getInstance(String transformation, String canon) 365 throws XMLEncryptionException { 366 XMLCipher instance = XMLCipher.getInstance(transformation); 367 368 if (canon != null) { 369 try { 370 instance._canon = Canonicalizer.getInstance(canon); 371 } catch (InvalidCanonicalizerException ice) { 372 throw new XMLEncryptionException("empty", ice); 373 } 374 } 375 376 return instance; 377 } 378 379 380 391 392 public static XMLCipher getProviderInstance(String transformation, String provider) 393 throws XMLEncryptionException { 394 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher..."); 396 if (null == transformation) 397 logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null..."); 398 if(null == provider) 399 logger.log(java.util.logging.Level.SEVERE, "Provider unexpectedly null.."); 400 if("" == provider) 401 logger.log(java.util.logging.Level.SEVERE, "Provider's value unexpectedly not specified..."); 402 if(!isValidEncryptionAlgorithm(transformation)) 403 logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS); 404 405 XMLCipher instance = new XMLCipher(); 406 407 instance._algorithm = transformation; 408 instance._requestedJCEProvider = provider; 409 instance._key = null; 410 instance._kek = null; 411 412 414 415 try { 416 instance._canon = Canonicalizer.getInstance 417 (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS); 418 } catch (InvalidCanonicalizerException ice) { 419 throw new XMLEncryptionException("empty", ice); 420 } 421 422 try { 423 String jceAlgorithm = 424 JCEMapper.translateURItoJCEID(transformation); 425 426 instance._contextCipher = Cipher.getInstance(jceAlgorithm, provider); 427 428 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "cipher._algorithm = " + 429 instance._contextCipher.getAlgorithm()); 430 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "provider.name = " + provider); 431 } catch (NoSuchAlgorithmException nsae) { 432 throw new XMLEncryptionException("empty", nsae); 433 } catch (NoSuchProviderException nspre) { 434 throw new XMLEncryptionException("empty", nspre); 435 } catch (NoSuchPaddingException nspe) { 436 throw new XMLEncryptionException("empty", nspe); 437 } 438 439 return (instance); 440 } 441 442 459 public static XMLCipher getProviderInstance( 460 String transformation, 461 String provider, 462 String canon) 463 throws XMLEncryptionException { 464 465 XMLCipher instance = XMLCipher.getProviderInstance(transformation, provider); 466 if (canon != null) { 467 try { 468 instance._canon = Canonicalizer.getInstance(canon); 469 } catch (InvalidCanonicalizerException ice) { 470 throw new XMLEncryptionException("empty", ice); 471 } 472 } 473 return instance; 474 } 475 476 485 486 public static XMLCipher getInstance() 487 throws XMLEncryptionException { 488 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher for no transformation..."); 490 491 XMLCipher instance = new XMLCipher(); 492 493 instance._algorithm = null; 494 instance._requestedJCEProvider = null; 495 instance._key = null; 496 instance._kek = null; 497 instance._contextCipher = null; 498 499 501 502 try { 503 instance._canon = Canonicalizer.getInstance 504 (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS); 505 } catch (InvalidCanonicalizerException ice) { 506 throw new XMLEncryptionException("empty", ice); 507 } 508 509 return (instance); 510 } 511 512 526 527 public static XMLCipher getProviderInstance(String provider) 528 throws XMLEncryptionException { 529 531 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Getting XMLCipher, provider but no transformation"); 532 if(null == provider) 533 logger.log(java.util.logging.Level.SEVERE, "Provider unexpectedly null.."); 534 if("" == provider) 535 logger.log(java.util.logging.Level.SEVERE, "Provider's value unexpectedly not specified..."); 536 537 XMLCipher instance = new XMLCipher(); 538 539 instance._algorithm = null; 540 instance._requestedJCEProvider = provider; 541 instance._key = null; 542 instance._kek = null; 543 instance._contextCipher = null; 544 545 try { 546 instance._canon = Canonicalizer.getInstance 547 (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS); 548 } catch (InvalidCanonicalizerException ice) { 549 throw new XMLEncryptionException("empty", ice); 550 } 551 552 return (instance); 553 } 554 555 575 public void init(int opmode, Key key) throws XMLEncryptionException { 576 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Initializing XMLCipher..."); 578 579 _ek = null; 580 _ed = null; 581 582 switch (opmode) { 583 584 case ENCRYPT_MODE : 585 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = ENCRYPT_MODE"); 586 _ed = createEncryptedData(CipherData.VALUE_TYPE, "NO VALUE YET"); 587 break; 588 case DECRYPT_MODE : 589 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = DECRYPT_MODE"); 590 break; 591 case WRAP_MODE : 592 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = WRAP_MODE"); 593 _ek = createEncryptedKey(CipherData.VALUE_TYPE, "NO VALUE YET"); 594 break; 595 case UNWRAP_MODE : 596 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "opmode = UNWRAP_MODE"); 597 break; 598 default : 599 logger.log(java.util.logging.Level.SEVERE, "Mode unexpectedly invalid"); 600 throw new XMLEncryptionException("Invalid mode in init"); 601 } 602 603 _cipherMode = opmode; 604 _key = key; 605 606 } 607 608 617 618 public EncryptedData getEncryptedData() { 619 620 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Returning EncryptedData"); 622 return _ed; 623 624 } 625 626 635 636 public EncryptedKey getEncryptedKey() { 637 638 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Returning EncryptedKey"); 640 return _ek; 641 } 642 643 653 654 public void setKEK(Key kek) { 655 656 _kek = kek; 657 658 } 659 660 673 674 public Element martial(EncryptedData encryptedData) { 675 676 return (_factory.toElement (encryptedData)); 677 678 } 679 680 693 694 public Element martial(EncryptedKey encryptedKey) { 695 696 return (_factory.toElement (encryptedKey)); 697 698 } 699 700 710 711 public Element martial(Document context, EncryptedData encryptedData) { 712 713 _contextDocument = context; 714 return (_factory.toElement (encryptedData)); 715 716 } 717 718 728 729 public Element martial(Document context, EncryptedKey encryptedKey) { 730 731 _contextDocument = context; 732 return (_factory.toElement (encryptedKey)); 733 734 } 735 736 747 748 private Document encryptElement(Element element) throws Exception { 749 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "Encrypting element..."); 750 if(null == element) 751 logger.log(java.util.logging.Level.SEVERE, "Element unexpectedly null..."); 752 if(_cipherMode != ENCRYPT_MODE) 753 if (logger.isLoggable(java.util.logging.Level.FINE)) logger.log(java.util.logging.Level.FINE, "XMLCipher unexpectedly not in ENCRYPT_MODE..."); 754 755 if (_algorithm == null) { 756 throw new XMLEncryptionException("XMLCipher instance without transformation specified"); 757 } 758 encryptData(_contextDocument, element, false); 759 760 Element encryptedElement = _factory.toElement(_ed); 761 762 Node sourceParent = element.getParentNode(); 763 sourceParent.replaceChild(encryptedElement, element); 764 765 return (_contextDocument); 766 } 767 768 782 private Document encryptElementContent(Element element) throws 783 Exception { 784 |