1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /**
   6  * Licensed to the Apache Software Foundation (ASF) under one
   7  * or more contributor license agreements. See the NOTICE file
   8  * distributed with this work for additional information
   9  * regarding copyright ownership. The ASF licenses this file
  10  * to you under the Apache License, Version 2.0 (the
  11  * "License"); you may not use this file except in compliance
  12  * with the License. You may obtain a copy of the License at
  13  *
  14  * http://www.apache.org/licenses/LICENSE-2.0
  15  *
  16  * Unless required by applicable law or agreed to in writing,
  17  * software distributed under the License is distributed on an
  18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  19  * KIND, either express or implied. See the License for the
  20  * specific language governing permissions and limitations
  21  * under the License.
  22  */
  23 /*
  24  * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
  25  */
  26 /*
  27  * $Id: DOMXMLSignatureFactory.java 1333869 2012-05-04 10:42:44Z coheigea $
  28  */
  29 package org.jcp.xml.dsig.internal.dom;
  30 
  31 import javax.xml.crypto.*;
  32 import javax.xml.crypto.dom.DOMCryptoContext;
  33 import javax.xml.crypto.dsig.*;
  34 import javax.xml.crypto.dsig.dom.DOMValidateContext;
  35 import javax.xml.crypto.dsig.keyinfo.*;
  36 import javax.xml.crypto.dsig.spec.*;
  37 
  38 import java.security.InvalidAlgorithmParameterException;
  39 import java.security.NoSuchAlgorithmException;
  40 import java.util.List;
  41 import org.w3c.dom.Document;
  42 import org.w3c.dom.Element;
  43 import org.w3c.dom.Node;
  44 
  45 /**
  46  * DOM-based implementation of XMLSignatureFactory.
  47  *
  48  * @author Sean Mullan
  49  */
  50 public final class DOMXMLSignatureFactory extends XMLSignatureFactory {
  51 
  52     /**
  53      * Initializes a new instance of this class.
  54      */
  55     public DOMXMLSignatureFactory() {}
  56 
  57     public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki) {
  58         return new DOMXMLSignature(si, ki, null, null, null);
  59     }
  60 
  61     @SuppressWarnings({ "unchecked", "rawtypes" })
  62     public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki,
  63         List objects, String id, String signatureValueId) {
  64         return new DOMXMLSignature(si, ki, objects, id, signatureValueId);
  65     }
  66 
  67     public Reference newReference(String uri, DigestMethod dm) {
  68         return newReference(uri, dm, null, null, null);
  69     }
  70 
  71     @SuppressWarnings({ "unchecked", "rawtypes" })
  72     public Reference newReference(String uri, DigestMethod dm, List transforms,
  73         String type, String id) {
  74         return new DOMReference(uri, type, dm, transforms, id, getProvider());
  75     }
  76 
  77     @SuppressWarnings({ "unchecked", "rawtypes" })
  78     public Reference newReference(String uri, DigestMethod dm,
  79         List appliedTransforms, Data result, List transforms, String type,
  80         String id) {
  81         if (appliedTransforms == null) {
  82             throw new NullPointerException("appliedTransforms cannot be null");
  83         }
  84         if (appliedTransforms.isEmpty()) {
  85             throw new NullPointerException("appliedTransforms cannot be empty");
  86         }
  87         if (result == null) {
  88             throw new NullPointerException("result cannot be null");
  89         }
  90         return new DOMReference
  91             (uri, type, dm, appliedTransforms, result, transforms, id, getProvider());
  92     }
  93 
  94     @SuppressWarnings({ "unchecked", "rawtypes" })
  95     public Reference newReference(String uri, DigestMethod dm, List transforms,
  96         String type, String id, byte[] digestValue) {
  97         if (digestValue == null) {
  98             throw new NullPointerException("digestValue cannot be null");
  99         }
 100         return new DOMReference
 101             (uri, type, dm, null, null, transforms, id, digestValue, getProvider());
 102     }
 103 
 104     @SuppressWarnings("rawtypes")
 105     public SignedInfo newSignedInfo(CanonicalizationMethod cm,
 106         SignatureMethod sm, List references) {
 107         return newSignedInfo(cm, sm, references, null);
 108     }
 109 
 110     @SuppressWarnings({ "unchecked", "rawtypes" })
 111     public SignedInfo newSignedInfo(CanonicalizationMethod cm,
 112         SignatureMethod sm, List references, String id) {
 113         return new DOMSignedInfo(cm, sm, references, id);
 114     }
 115 
 116     // Object factory methods
 117     @SuppressWarnings({ "unchecked", "rawtypes" })
 118     public XMLObject newXMLObject(List content, String id, String mimeType,
 119         String encoding) {
 120         return new DOMXMLObject(content, id, mimeType, encoding);
 121     }
 122 
 123     @SuppressWarnings("rawtypes")
 124     public Manifest newManifest(List references) {
 125         return newManifest(references, null);
 126     }
 127 
 128     @SuppressWarnings({ "unchecked", "rawtypes" })
 129     public Manifest newManifest(List references, String id) {
 130         return new DOMManifest(references, id);
 131     }
 132 
 133     @SuppressWarnings({ "unchecked", "rawtypes" })
 134     public SignatureProperties newSignatureProperties(List props, String id) {
 135         return new DOMSignatureProperties(props, id);
 136     }
 137 
 138     @SuppressWarnings({ "unchecked", "rawtypes" })
 139     public SignatureProperty newSignatureProperty
 140         (List info, String target, String id) {
 141         return new DOMSignatureProperty(info, target, id);
 142     }
 143 
 144     public XMLSignature unmarshalXMLSignature(XMLValidateContext context)
 145         throws MarshalException {
 146 
 147         if (context == null) {
 148             throw new NullPointerException("context cannot be null");
 149         }
 150         return unmarshal(((DOMValidateContext) context).getNode(), context);
 151     }
 152 
 153     public XMLSignature unmarshalXMLSignature(XMLStructure xmlStructure)
 154         throws MarshalException {
 155 
 156         if (xmlStructure == null) {
 157             throw new NullPointerException("xmlStructure cannot be null");
 158         }
 159         if (!(xmlStructure instanceof javax.xml.crypto.dom.DOMStructure)) {
 160             throw new ClassCastException("xmlStructure must be of type DOMStructure");
 161         }
 162         return unmarshal
 163             (((javax.xml.crypto.dom.DOMStructure) xmlStructure).getNode(),
 164              new UnmarshalContext());
 165     }
 166 
 167     private static class UnmarshalContext extends DOMCryptoContext {
 168         UnmarshalContext() {}
 169     }
 170 
 171     private XMLSignature unmarshal(Node node, XMLCryptoContext context)
 172         throws MarshalException {
 173 
 174         node.normalize();
 175 
 176         Element element = null;
 177         if (node.getNodeType() == Node.DOCUMENT_NODE) {
 178             element = ((Document) node).getDocumentElement();
 179         } else if (node.getNodeType() == Node.ELEMENT_NODE) {
 180             element = (Element) node;
 181         } else {
 182             throw new MarshalException
 183                 ("Signature element is not a proper Node");
 184         }
 185 
 186         // check tag
 187         String tag = element.getLocalName();
 188         if (tag == null) {
 189             throw new MarshalException("Document implementation must " +
 190                 "support DOM Level 2 and be namespace aware");
 191         }
 192         if (tag.equals("Signature")) {
 193             return new DOMXMLSignature(element, context, getProvider());
 194         } else {
 195             throw new MarshalException("invalid Signature tag: " + tag);
 196         }
 197     }
 198 
 199     public boolean isFeatureSupported(String feature) {
 200         if (feature == null) {
 201             throw new NullPointerException();
 202         } else {
 203             return false;
 204         }
 205     }
 206 
 207     public DigestMethod newDigestMethod(String algorithm,
 208         DigestMethodParameterSpec params) throws NoSuchAlgorithmException,
 209         InvalidAlgorithmParameterException {
 210         if (algorithm == null) {
 211             throw new NullPointerException();
 212         }
 213         if (algorithm.equals(DigestMethod.SHA1)) {
 214             return new DOMDigestMethod.SHA1(params);
 215         } else if (algorithm.equals(DigestMethod.SHA256)) {
 216             return new DOMDigestMethod.SHA256(params);
 217         } else if (algorithm.equals(DOMDigestMethod.SHA384)) {
 218             return new DOMDigestMethod.SHA384(params);
 219         } else if (algorithm.equals(DigestMethod.SHA512)) {
 220             return new DOMDigestMethod.SHA512(params);
 221         } else {
 222             throw new NoSuchAlgorithmException("unsupported algorithm");
 223         }
 224     }
 225 
 226     public SignatureMethod newSignatureMethod(String algorithm,
 227         SignatureMethodParameterSpec params) throws NoSuchAlgorithmException,
 228         InvalidAlgorithmParameterException {
 229         if (algorithm == null) {
 230             throw new NullPointerException();
 231         }
 232         if (algorithm.equals(SignatureMethod.RSA_SHA1)) {
 233             return new DOMSignatureMethod.SHA1withRSA(params);
 234         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA256)) {
 235             return new DOMSignatureMethod.SHA256withRSA(params);
 236         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA384)) {
 237             return new DOMSignatureMethod.SHA384withRSA(params);
 238         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512)) {
 239             return new DOMSignatureMethod.SHA512withRSA(params);
 240         } else if (algorithm.equals(SignatureMethod.DSA_SHA1)) {
 241             return new DOMSignatureMethod.SHA1withDSA(params);
 242         } else if (algorithm.equals(DOMSignatureMethod.DSA_SHA256)) {
 243             return new DOMSignatureMethod.SHA256withDSA(params);
 244         } else if (algorithm.equals(SignatureMethod.HMAC_SHA1)) {
 245             return new DOMHMACSignatureMethod.SHA1(params);
 246         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA256)) {
 247             return new DOMHMACSignatureMethod.SHA256(params);
 248         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA384)) {
 249             return new DOMHMACSignatureMethod.SHA384(params);
 250         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA512)) {
 251             return new DOMHMACSignatureMethod.SHA512(params);
 252         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA1)) {
 253             return new DOMSignatureMethod.SHA1withECDSA(params);
 254         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA256)) {
 255             return new DOMSignatureMethod.SHA256withECDSA(params);
 256         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA384)) {
 257             return new DOMSignatureMethod.SHA384withECDSA(params);
 258         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA512)) {
 259             return new DOMSignatureMethod.SHA512withECDSA(params);
 260         } else {
 261             throw new NoSuchAlgorithmException("unsupported algorithm");
 262         }
 263     }
 264 
 265     public Transform newTransform(String algorithm,
 266         TransformParameterSpec params) throws NoSuchAlgorithmException,
 267         InvalidAlgorithmParameterException {
 268 
 269         TransformService spi;
 270         if (getProvider() == null) {
 271             spi = TransformService.getInstance(algorithm, "DOM");
 272         } else {
 273             try {
 274                 spi = TransformService.getInstance(algorithm, "DOM", getProvider());
 275             } catch (NoSuchAlgorithmException nsae) {
 276                 spi = TransformService.getInstance(algorithm, "DOM");
 277             }
 278         }
 279 
 280         spi.init(params);
 281         return new DOMTransform(spi);
 282     }
 283 
 284     public Transform newTransform(String algorithm,
 285         XMLStructure params) throws NoSuchAlgorithmException,
 286         InvalidAlgorithmParameterException {
 287         TransformService spi;
 288         if (getProvider() == null) {
 289             spi = TransformService.getInstance(algorithm, "DOM");
 290         } else {
 291             try {
 292                 spi = TransformService.getInstance(algorithm, "DOM", getProvider());
 293             } catch (NoSuchAlgorithmException nsae) {
 294                 spi = TransformService.getInstance(algorithm, "DOM");
 295             }
 296         }
 297 
 298         if (params == null) {
 299             spi.init(null);
 300         } else {
 301             spi.init(params, null);
 302         }
 303         return new DOMTransform(spi);
 304     }
 305 
 306     public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
 307         C14NMethodParameterSpec params) throws NoSuchAlgorithmException,
 308         InvalidAlgorithmParameterException {
 309         TransformService spi;
 310         if (getProvider() == null) {
 311             spi = TransformService.getInstance(algorithm, "DOM");
 312         } else {
 313             try {
 314                 spi = TransformService.getInstance(algorithm, "DOM", getProvider());
 315             } catch (NoSuchAlgorithmException nsae) {
 316                 spi = TransformService.getInstance(algorithm, "DOM");
 317             }
 318         }
 319 
 320         spi.init(params);
 321         return new DOMCanonicalizationMethod(spi);
 322     }
 323 
 324     public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
 325         XMLStructure params) throws NoSuchAlgorithmException,
 326         InvalidAlgorithmParameterException {
 327         TransformService spi;
 328         if (getProvider() == null) {
 329             spi = TransformService.getInstance(algorithm, "DOM");
 330         } else {
 331             try {
 332                 spi = TransformService.getInstance(algorithm, "DOM", getProvider());
 333             } catch (NoSuchAlgorithmException nsae) {
 334                 spi = TransformService.getInstance(algorithm, "DOM");
 335             }
 336         }
 337         if (params == null) {
 338             spi.init(null);
 339         } else {
 340             spi.init(params, null);
 341         }
 342 
 343         return new DOMCanonicalizationMethod(spi);
 344     }
 345 
 346     public URIDereferencer getURIDereferencer() {
 347         return DOMURIDereferencer.INSTANCE;
 348     }
 349 }