1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2005 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 * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. 23 */ 24 /* 25 * $Id: DOMExcC14NMethod.java,v 1.2 2008/07/24 15:20:32 mullan Exp $ 26 */ 27 package org.jcp.xml.dsig.internal.dom; 28 29 import javax.xml.crypto.*; 30 import javax.xml.crypto.dsig.*; 31 import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; 32 import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec; 33 import javax.xml.crypto.dsig.spec.TransformParameterSpec; 34 35 import java.security.InvalidAlgorithmParameterException; 36 import java.security.spec.AlgorithmParameterSpec; 37 import java.util.*; 38 import org.w3c.dom.Element; 39 40 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; 41 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException; 42 43 /** 44 * DOM-based implementation of CanonicalizationMethod for Exclusive 45 * Canonical XML algorithm (with or without comments). 46 * Uses Apache XML-Sec Canonicalizer. 47 * 48 * @author Sean Mullan 49 */ 50 public final class DOMExcC14NMethod extends ApacheCanonicalizer { 51 52 public void init(TransformParameterSpec params) 53 throws InvalidAlgorithmParameterException { 54 if (params != null) { 55 if (!(params instanceof ExcC14NParameterSpec)) { 56 throw new InvalidAlgorithmParameterException 57 ("params must be of type ExcC14NParameterSpec"); 58 } 59 this.params = (C14NMethodParameterSpec) params; 60 } 61 } 62 63 public void init(XMLStructure parent, XMLCryptoContext context) 64 throws InvalidAlgorithmParameterException { 65 super.init(parent, context); 66 Element paramsElem = DOMUtils.getFirstChildElement(transformElem); 67 if (paramsElem == null) { 68 this.params = null; 69 this.inclusiveNamespaces = null; 70 return; 71 } 72 unmarshalParams(paramsElem); 73 } 74 75 private void unmarshalParams(Element paramsElem) { 76 String prefixListAttr = paramsElem.getAttributeNS(null, "PrefixList"); 77 this.inclusiveNamespaces = prefixListAttr; 78 int begin = 0; 79 int end = prefixListAttr.indexOf(' '); 80 List prefixList = new ArrayList(); 81 while (end != -1) { 82 prefixList.add(prefixListAttr.substring(begin, end)); 83 begin = end + 1; 84 end = prefixListAttr.indexOf(' ', begin); 85 } 86 if (begin <= prefixListAttr.length()) { 87 prefixList.add(prefixListAttr.substring(begin)); 88 } 89 this.params = new ExcC14NParameterSpec(prefixList); 90 } 91 92 public void marshalParams(XMLStructure parent, XMLCryptoContext context) 93 throws MarshalException { 94 95 super.marshalParams(parent, context); 96 AlgorithmParameterSpec spec = getParameterSpec(); 97 if (spec == null) { 98 return; 99 } 100 101 String prefix = 102 DOMUtils.getNSPrefix(context, CanonicalizationMethod.EXCLUSIVE); 103 Element excElem = DOMUtils.createElement 104 (ownerDoc, "InclusiveNamespaces", 105 CanonicalizationMethod.EXCLUSIVE, prefix); 106 if (prefix == null || prefix.length() == 0) { 107 excElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", 108 CanonicalizationMethod.EXCLUSIVE); 109 } else { 110 excElem.setAttributeNS("http://www.w3.org/2000/xmlns/", 111 "xmlns:" + prefix, CanonicalizationMethod.EXCLUSIVE); 112 } 113 114 ExcC14NParameterSpec params = (ExcC14NParameterSpec) spec; 115 StringBuffer prefixListAttr = new StringBuffer(""); 116 List prefixList = params.getPrefixList(); 117 for (int i = 0, size = prefixList.size(); i < size; i++) { 118 prefixListAttr.append((String) prefixList.get(i)); 119 if (i < size - 1) { 120 prefixListAttr.append(" "); 121 } 122 } 123 DOMUtils.setAttribute(excElem, "PrefixList", prefixListAttr.toString()); 124 this.inclusiveNamespaces = prefixListAttr.toString(); 125 transformElem.appendChild(excElem); 126 } 127 128 public String getParamsNSURI() { 129 return CanonicalizationMethod.EXCLUSIVE; 130 } 131 132 public Data transform(Data data, XMLCryptoContext xc) 133 throws TransformException { 134 135 // ignore comments if dereferencing same-document URI that require 136 // you to omit comments, even if the Transform says otherwise - 137 // this is to be compliant with section 4.3.3.3 of W3C Rec. 138 if (data instanceof DOMSubTreeData) { 139 DOMSubTreeData subTree = (DOMSubTreeData) data; 140 if (subTree.excludeComments()) { 141 try { 142 apacheCanonicalizer = Canonicalizer.getInstance 143 (CanonicalizationMethod.EXCLUSIVE); 144 } catch (InvalidCanonicalizerException ice) { 145 throw new TransformException 146 ("Couldn't find Canonicalizer for: " + 147 CanonicalizationMethod.EXCLUSIVE + ": " + 148 ice.getMessage(), ice); 149 } 150 } 151 } 152 153 return canonicalize(data, xc); 154 } 155 }