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