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: DOMKeyInfoFactory.java 1854026 2019-02-21 09:30:01Z coheigea $ 28 */ 29 package org.jcp.xml.dsig.internal.dom; 30 31 import java.math.BigInteger; 32 import java.security.KeyException; 33 import java.security.PublicKey; 34 import java.security.interfaces.ECPublicKey; 35 import java.security.interfaces.DSAPublicKey; 36 import java.security.interfaces.RSAPublicKey; 37 import java.util.List; 38 39 import javax.xml.crypto.MarshalException; 40 import javax.xml.crypto.URIDereferencer; 41 import javax.xml.crypto.XMLStructure; 42 import javax.xml.crypto.dom.DOMCryptoContext; 43 import javax.xml.crypto.dsig.XMLSignature; 44 import javax.xml.crypto.dsig.keyinfo.KeyInfo; 45 import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; 46 import javax.xml.crypto.dsig.keyinfo.KeyName; 47 import javax.xml.crypto.dsig.keyinfo.KeyValue; 48 import javax.xml.crypto.dsig.keyinfo.PGPData; 49 import javax.xml.crypto.dsig.keyinfo.RetrievalMethod; 50 import javax.xml.crypto.dsig.keyinfo.X509Data; 51 import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial; 52 53 import org.w3c.dom.Document; 54 import org.w3c.dom.Element; 55 import org.w3c.dom.Node; 56 57 /** 58 * DOM-based implementation of KeyInfoFactory. 59 * 60 */ 61 public final class DOMKeyInfoFactory extends KeyInfoFactory { 62 63 public DOMKeyInfoFactory() { } 64 65 @SuppressWarnings("rawtypes") 66 public KeyInfo newKeyInfo(List content) { 67 return newKeyInfo(content, null); 68 } 69 70 @SuppressWarnings({ "unchecked", "rawtypes" }) 71 public KeyInfo newKeyInfo(List content, String id) { 72 return new DOMKeyInfo(content, id); 73 } 74 75 public KeyName newKeyName(String name) { 76 return new DOMKeyName(name); 77 } 78 79 public KeyValue newKeyValue(PublicKey key) throws KeyException { 80 String algorithm = key.getAlgorithm(); 81 if ("DSA".equals(algorithm)) { 82 return new DOMKeyValue.DSA((DSAPublicKey) key); 83 } else if ("RSA".equals(algorithm)) { 84 return new DOMKeyValue.RSA((RSAPublicKey) key); 85 } else if ("EC".equals(algorithm)) { 86 return new DOMKeyValue.EC((ECPublicKey) key); 87 } else { 88 throw new KeyException("unsupported key algorithm: " + algorithm); 89 } 90 } 91 92 public PGPData newPGPData(byte[] keyId) { 93 return newPGPData(keyId, null, null); 94 } 95 96 @SuppressWarnings({ "rawtypes", "unchecked" }) 97 public PGPData newPGPData(byte[] keyId, byte[] keyPacket, List other) { 98 return new DOMPGPData(keyId, keyPacket, other); 99 } 100 101 @SuppressWarnings({ "rawtypes", "unchecked" }) 102 public PGPData newPGPData(byte[] keyPacket, List other) { 103 return new DOMPGPData(keyPacket, other); 104 } 105 106 public RetrievalMethod newRetrievalMethod(String uri) { 107 return newRetrievalMethod(uri, null, null); 108 } 109 110 @SuppressWarnings({ "rawtypes", "unchecked" }) 111 public RetrievalMethod newRetrievalMethod(String uri, String type, 112 List transforms) { 113 if (uri == null) { 114 throw new NullPointerException("uri must not be null"); 115 } 116 return new DOMRetrievalMethod(uri, type, transforms); 117 } 118 119 @SuppressWarnings({ "rawtypes" }) 120 public X509Data newX509Data(List content) { 121 return new DOMX509Data(content); 122 } 123 124 @Override 125 public X509IssuerSerial newX509IssuerSerial(String issuerName, 126 BigInteger serialNumber) { 127 return new DOMX509IssuerSerial(issuerName, serialNumber); 128 } 129 130 public boolean isFeatureSupported(String feature) { 131 if (feature == null) { 132 throw new NullPointerException(); 133 } else { 134 return false; 135 } 136 } 137 138 public URIDereferencer getURIDereferencer() { 139 return DOMURIDereferencer.INSTANCE; 140 } 141 142 @Override 143 public KeyInfo unmarshalKeyInfo(XMLStructure xmlStructure) 144 throws MarshalException { 145 if (xmlStructure == null) { 146 throw new NullPointerException("xmlStructure cannot be null"); 147 } 148 if (!(xmlStructure instanceof javax.xml.crypto.dom.DOMStructure)) { 149 throw new ClassCastException("xmlStructure must be of type DOMStructure"); 150 } 151 Node node = 152 ((javax.xml.crypto.dom.DOMStructure) xmlStructure).getNode(); 153 node.normalize(); 154 155 Element element = null; 156 if (node.getNodeType() == Node.DOCUMENT_NODE) { 157 element = ((Document) node).getDocumentElement(); 158 } else if (node.getNodeType() == Node.ELEMENT_NODE) { 159 element = (Element) node; 160 } else { 161 throw new MarshalException 162 ("xmlStructure does not contain a proper Node"); 163 } 164 165 // check tag 166 String tag = element.getLocalName(); 167 String namespace = element.getNamespaceURI(); 168 if (tag == null || namespace == null) { 169 throw new MarshalException("Document implementation must " + 170 "support DOM Level 2 and be namespace aware"); 171 } 172 if ("KeyInfo".equals(tag) && XMLSignature.XMLNS.equals(namespace)) { 173 try { 174 return new DOMKeyInfo(element, new UnmarshalContext(), getProvider()); 175 } catch (MarshalException me) { 176 throw me; 177 } catch (Exception e) { 178 throw new MarshalException(e); 179 } 180 } else { 181 throw new MarshalException("Invalid KeyInfo tag: " + namespace + ":" + tag); 182 } 183 } 184 185 private static class UnmarshalContext extends DOMCryptoContext { 186 UnmarshalContext() {} 187 } 188 189 }