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, 2019, Oracle and/or its affiliates. All rights reserved.
  25  */
  26 /*
  27  * $Id: DOMXMLSignatureFactory.java 1854026 2019-02-21 09:30:01Z 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 
  42 import org.w3c.dom.Document;
  43 import org.w3c.dom.Element;
  44 import org.w3c.dom.Node;
  45 
  46 /**
  47  * DOM-based implementation of XMLSignatureFactory.
  48  *
  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     @Override
  78     @SuppressWarnings({ "unchecked", "rawtypes" })
  79     public Reference newReference(String uri, DigestMethod dm,
  80         List appliedTransforms, Data result, List transforms, String type,
  81         String id) {
  82         if (appliedTransforms == null) {
  83             throw new NullPointerException("appliedTransforms cannot be null");
  84         }
  85         if (appliedTransforms.isEmpty()) {
  86             throw new NullPointerException("appliedTransforms cannot be empty");
  87         }
  88         if (result == null) {
  89             throw new NullPointerException("result cannot be null");
  90         }
  91         return new DOMReference
  92             (uri, type, dm, appliedTransforms, result, transforms, id, getProvider());
  93     }
  94 
  95     @SuppressWarnings({ "unchecked", "rawtypes" })
  96     public Reference newReference(String uri, DigestMethod dm, List transforms,
  97         String type, String id, byte[] digestValue) {
  98         if (digestValue == null) {
  99             throw new NullPointerException("digestValue cannot be null");
 100         }
 101         return new DOMReference
 102             (uri, type, dm, null, null, transforms, id, digestValue, getProvider());
 103     }
 104 
 105     @SuppressWarnings({ "rawtypes" })
 106     public SignedInfo newSignedInfo(CanonicalizationMethod cm,
 107         SignatureMethod sm, List references) {
 108         return newSignedInfo(cm, sm, references, null);
 109     }
 110 
 111     @SuppressWarnings({ "unchecked", "rawtypes" })
 112     public SignedInfo newSignedInfo(CanonicalizationMethod cm,
 113         SignatureMethod sm, List references, String id) {
 114         return new DOMSignedInfo(cm, sm, references, id);
 115     }
 116 
 117     // Object factory methods
 118     @SuppressWarnings({ "unchecked", "rawtypes" })
 119     public XMLObject newXMLObject(List content, String id, String mimeType,
 120         String encoding) {
 121         return new DOMXMLObject(content, id, mimeType, encoding);
 122     }
 123 
 124     @SuppressWarnings({ "rawtypes" })
 125     public Manifest newManifest(List references) {
 126         return newManifest(references, null);
 127     }
 128 
 129     @SuppressWarnings({ "unchecked", "rawtypes" })
 130     public Manifest newManifest(List references, String id) {
 131         return new DOMManifest(references, id);
 132     }
 133 
 134     @SuppressWarnings({ "unchecked", "rawtypes" })
 135     public SignatureProperties newSignatureProperties(List props, String id) {
 136         return new DOMSignatureProperties(props, id);
 137     }
 138 
 139     @SuppressWarnings({ "unchecked", "rawtypes" })
 140     public SignatureProperty newSignatureProperty
 141         (List info, String target, String id) {
 142         return new DOMSignatureProperty(info, target, id);
 143     }
 144 
 145     public XMLSignature unmarshalXMLSignature(XMLValidateContext context)
 146         throws MarshalException {
 147 
 148         if (context == null) {
 149             throw new NullPointerException("context cannot be null");
 150         }
 151         return unmarshal(((DOMValidateContext) context).getNode(), context);
 152     }
 153 
 154     public XMLSignature unmarshalXMLSignature(XMLStructure xmlStructure)
 155         throws MarshalException {
 156 
 157         if (xmlStructure == null) {
 158             throw new NullPointerException("xmlStructure cannot be null");
 159         }
 160         if (!(xmlStructure instanceof javax.xml.crypto.dom.DOMStructure)) {
 161             throw new ClassCastException("xmlStructure must be of type DOMStructure");
 162         }
 163         return unmarshal
 164             (((javax.xml.crypto.dom.DOMStructure) xmlStructure).getNode(),
 165              new UnmarshalContext());
 166     }
 167 
 168     private static class UnmarshalContext extends DOMCryptoContext {
 169         UnmarshalContext() {}
 170     }
 171 
 172     private XMLSignature unmarshal(Node node, XMLCryptoContext context)
 173         throws MarshalException {
 174 
 175         node.normalize();
 176 
 177         Element element = null;
 178         if (node.getNodeType() == Node.DOCUMENT_NODE) {
 179             element = ((Document) node).getDocumentElement();
 180         } else if (node.getNodeType() == Node.ELEMENT_NODE) {
 181             element = (Element) node;
 182         } else {
 183             throw new MarshalException
 184                 ("Signature element is not a proper Node");
 185         }
 186 
 187         // check tag
 188         String tag = element.getLocalName();
 189         String namespace = element.getNamespaceURI();
 190         if (tag == null || namespace == null) {
 191             throw new MarshalException("Document implementation must " +
 192                 "support DOM Level 2 and be namespace aware");
 193         }
 194         if ("Signature".equals(tag) && XMLSignature.XMLNS.equals(namespace)) {
 195             return new DOMXMLSignature(element, context, getProvider());
 196         } else {
 197             throw new MarshalException("invalid Signature tag: " + namespace + ":" + tag);
 198         }
 199     }
 200 
 201     public boolean isFeatureSupported(String feature) {
 202         if (feature == null) {
 203             throw new NullPointerException();
 204         } else {
 205             return false;
 206         }
 207     }
 208 
 209     public DigestMethod newDigestMethod(String algorithm,
 210         DigestMethodParameterSpec params) throws NoSuchAlgorithmException,
 211         InvalidAlgorithmParameterException {
 212         if (algorithm == null) {
 213             throw new NullPointerException();
 214         }
 215         if (algorithm.equals(DigestMethod.SHA1)) {
 216             return new DOMDigestMethod.SHA1(params);
 217         } else if (algorithm.equals(DOMDigestMethod.SHA224)) {
 218             return new DOMDigestMethod.SHA224(params);
 219         } else if (algorithm.equals(DigestMethod.SHA256)) {
 220             return new DOMDigestMethod.SHA256(params);
 221         } else if (algorithm.equals(DOMDigestMethod.SHA384)) {
 222             return new DOMDigestMethod.SHA384(params);
 223         } else if (algorithm.equals(DigestMethod.SHA512)) {
 224             return new DOMDigestMethod.SHA512(params);
 225         } else if (algorithm.equals(DigestMethod.RIPEMD160)) {
 226             return new DOMDigestMethod.RIPEMD160(params);
 227         } else if (algorithm.equals(DOMDigestMethod.WHIRLPOOL)) {
 228             return new DOMDigestMethod.WHIRLPOOL(params);
 229         } else if (algorithm.equals(DOMDigestMethod.SHA3_224)) {
 230             return new DOMDigestMethod.SHA3_224(params);
 231         } else if (algorithm.equals(DOMDigestMethod.SHA3_256)) {
 232             return new DOMDigestMethod.SHA3_256(params);
 233         } else if (algorithm.equals(DOMDigestMethod.SHA3_384)) {
 234             return new DOMDigestMethod.SHA3_384(params);
 235         } else if (algorithm.equals(DOMDigestMethod.SHA3_512)) {
 236             return new DOMDigestMethod.SHA3_512(params);
 237         } else {
 238             throw new NoSuchAlgorithmException("unsupported algorithm");
 239         }
 240     }
 241 
 242     public SignatureMethod newSignatureMethod(String algorithm,
 243         SignatureMethodParameterSpec params) throws NoSuchAlgorithmException,
 244         InvalidAlgorithmParameterException {
 245         if (algorithm == null) {
 246             throw new NullPointerException();
 247         }
 248         if (algorithm.equals(SignatureMethod.RSA_SHA1)) {
 249             return new DOMSignatureMethod.SHA1withRSA(params);
 250         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA224)) {
 251             return new DOMSignatureMethod.SHA224withRSA(params);
 252         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA256)) {
 253             return new DOMSignatureMethod.SHA256withRSA(params);
 254         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA384)) {
 255             return new DOMSignatureMethod.SHA384withRSA(params);
 256         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512)) {
 257             return new DOMSignatureMethod.SHA512withRSA(params);
 258         } else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160)) {
 259             return new DOMSignatureMethod.RIPEMD160withRSA(params);
 260         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA1_MGF1)) {
 261             return new DOMSignatureMethod.SHA1withRSAandMGF1(params);
 262         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA224_MGF1)) {
 263             return new DOMSignatureMethod.SHA224withRSAandMGF1(params);
 264         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA256_MGF1)) {
 265             return new DOMSignatureMethod.SHA256withRSAandMGF1(params);
 266         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA384_MGF1)) {
 267             return new DOMSignatureMethod.SHA384withRSAandMGF1(params);
 268         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512_MGF1)) {
 269             return new DOMSignatureMethod.SHA512withRSAandMGF1(params);
 270         } else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160_MGF1)) {
 271             return new DOMSignatureMethod.RIPEMD160withRSAandMGF1(params);
 272         } else if (algorithm.equals(SignatureMethod.DSA_SHA1)) {
 273             return new DOMSignatureMethod.SHA1withDSA(params);
 274         } else if (algorithm.equals(DOMSignatureMethod.DSA_SHA256)) {
 275             return new DOMSignatureMethod.SHA256withDSA(params);
 276         } else if (algorithm.equals(SignatureMethod.HMAC_SHA1)) {
 277             return new DOMHMACSignatureMethod.SHA1(params);
 278         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA224)) {
 279             return new DOMHMACSignatureMethod.SHA224(params);
 280         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA256)) {
 281             return new DOMHMACSignatureMethod.SHA256(params);
 282         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA384)) {
 283             return new DOMHMACSignatureMethod.SHA384(params);
 284         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA512)) {
 285             return new DOMHMACSignatureMethod.SHA512(params);
 286         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_RIPEMD160)) {
 287             return new DOMHMACSignatureMethod.RIPEMD160(params);
 288         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA1)) {
 289             return new DOMSignatureMethod.SHA1withECDSA(params);
 290         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA224)) {
 291             return new DOMSignatureMethod.SHA224withECDSA(params);
 292         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA256)) {
 293             return new DOMSignatureMethod.SHA256withECDSA(params);
 294         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA384)) {
 295             return new DOMSignatureMethod.SHA384withECDSA(params);
 296         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_SHA512)) {
 297             return new DOMSignatureMethod.SHA512withECDSA(params);
 298         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_RIPEMD160)) {
 299             return new DOMSignatureMethod.RIPEMD160withECDSA(params);
 300         }else {
 301             throw new NoSuchAlgorithmException("unsupported algorithm");
 302         }
 303     }
 304 
 305     public Transform newTransform(String algorithm,
 306         TransformParameterSpec params) throws NoSuchAlgorithmException,
 307         InvalidAlgorithmParameterException {
 308 
 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 DOMTransform(spi);
 322     }
 323 
 324     public Transform newTransform(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 
 338         if (params == null) {
 339             spi.init(null);
 340         } else {
 341             spi.init(params, null);
 342         }
 343         return new DOMTransform(spi);
 344     }
 345 
 346     public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
 347         C14NMethodParameterSpec params) throws NoSuchAlgorithmException,
 348         InvalidAlgorithmParameterException {
 349         TransformService spi;
 350         if (getProvider() == null) {
 351             spi = TransformService.getInstance(algorithm, "DOM");
 352         } else {
 353             try {
 354                 spi = TransformService.getInstance(algorithm, "DOM", getProvider());
 355             } catch (NoSuchAlgorithmException nsae) {
 356                 spi = TransformService.getInstance(algorithm, "DOM");
 357             }
 358         }
 359 
 360         spi.init(params);
 361         return new DOMCanonicalizationMethod(spi);
 362     }
 363 
 364     public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
 365         XMLStructure params) throws NoSuchAlgorithmException,
 366         InvalidAlgorithmParameterException {
 367         TransformService spi;
 368         if (getProvider() == null) {
 369             spi = TransformService.getInstance(algorithm, "DOM");
 370         } else {
 371             try {
 372                 spi = TransformService.getInstance(algorithm, "DOM", getProvider());
 373             } catch (NoSuchAlgorithmException nsae) {
 374                 spi = TransformService.getInstance(algorithm, "DOM");
 375             }
 376         }
 377         if (params == null) {
 378             spi.init(null);
 379         } else {
 380             spi.init(params, null);
 381         }
 382 
 383         return new DOMCanonicalizationMethod(spi);
 384     }
 385 
 386     public URIDereferencer getURIDereferencer() {
 387         return DOMURIDereferencer.INSTANCE;
 388     }
 389 }