001: /*
002: * KeyIdentifier.java
003: *
004: * Created on August 7, 2006, 1:48 PM
005: *
006: * The contents of this file are subject to the terms
007: * of the Common Development and Distribution License
008: * (the License). You may not use this file except in
009: * compliance with the License.
010: *
011: * You can obtain a copy of the license at
012: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
013: * See the License for the specific language governing
014: * permissions and limitations under the License.
015: *
016: * When distributing Covered Code, include this CDDL
017: * Header Notice in each file and include the License file
018: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
019: * If applicable, add the following below the CDDL Header,
020: * with the fields enclosed by brackets [] replaced by
021: * you own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
025: */
026:
027: package com.sun.xml.ws.security.opt.impl.reference;
028:
029: import com.sun.istack.NotNull;
030: import com.sun.xml.ws.security.opt.api.SecurityElementWriter;
031: import com.sun.xml.ws.security.opt.api.SecurityHeaderElement;
032: import com.sun.xml.wss.XWSSecurityException;
033: import java.io.IOException;
034: import java.security.MessageDigest;
035: import java.security.NoSuchAlgorithmException;
036: import java.security.cert.CertificateEncodingException;
037: import java.security.cert.X509Certificate;
038: import java.util.HashMap;
039: import java.util.Iterator;
040: import javax.xml.bind.JAXBException;
041: import javax.xml.bind.Marshaller;
042: import javax.xml.bind.JAXBElement;
043: import javax.xml.namespace.QName;
044: import javax.xml.stream.XMLStreamException;
045: import javax.xml.stream.XMLStreamReader;
046: import javax.xml.stream.XMLStreamWriter;
047:
048: import com.sun.xml.ws.security.secext10.KeyIdentifierType;
049: import com.sun.xml.ws.security.secext10.ObjectFactory;
050: import com.sun.xml.wss.impl.MessageConstants;
051: import com.sun.xml.stream.buffer.XMLStreamBufferResult;
052: import com.sun.xml.ws.security.opt.impl.util.JAXBUtil;
053: import com.sun.xml.wss.impl.misc.Base64;
054:
055: import java.util.Map;
056: import java.io.OutputStream;
057: import com.sun.xml.ws.api.SOAPVersion;
058:
059: /**
060: *
061: * @author Ashutosh.Shahi@sun.com
062: */
063: public class KeyIdentifier extends KeyIdentifierType implements
064: com.sun.xml.ws.security.opt.api.reference.KeyIdentifier,
065: SecurityHeaderElement, SecurityElementWriter {
066:
067: private SOAPVersion soapVersion = SOAPVersion.SOAP_11;
068:
069: /** Creates a new instance of KeyIdentifier */
070: public KeyIdentifier(SOAPVersion sv) {
071: this .soapVersion = sv;
072: }
073:
074: /**
075: *
076: * @return the valueType attribute for KeyIdentifier
077: */
078: public String getValueType() {
079: return super .getValueType();
080: }
081:
082: /**
083: *
084: * @param valueType the valueType attribute for KeyIdentifier
085: */
086: public void setValueType(final String valueType) {
087: super .setValueType(valueType);
088: }
089:
090: /**
091: *
092: * @return the encodingType attribute
093: */
094: public String getEncodingType() {
095: return super .getEncodingType();
096: }
097:
098: /**
099: *
100: * @param value the encodingType attribute
101: */
102: public void setEncodingType(final String value) {
103: super .setEncodingType(value);
104: }
105:
106: /**
107: *
108: * @return the referenced value by this key identifier
109: */
110: public String getReferenceValue() {
111: return super .getValue();
112: }
113:
114: /**
115: *
116: * @param referenceValue the referenced value by this keyIdentifier
117: */
118: public void setReferenceValue(final String referenceValue) {
119: super .setValue(referenceValue);
120: }
121:
122: /**
123: *
124: * @return the reference type used
125: */
126: public String getType() {
127: return MessageConstants.KEY_INDETIFIER_TYPE;
128: }
129:
130: /**
131: *
132: * @return id attribute
133: */
134: public String getId() {
135: QName qname = new QName(MessageConstants.WSU_NS, "Id",
136: MessageConstants.WSU_PREFIX);
137: Map<QName, String> otherAttributes = this .getOtherAttributes();
138: return otherAttributes.get(qname);
139: }
140:
141: /**
142: *
143: * @param id
144: */
145: public void setId(String id) {
146: QName qname = new QName(MessageConstants.WSU_NS, "Id",
147: MessageConstants.WSU_PREFIX);
148: Map<QName, String> otherAttributes = this .getOtherAttributes();
149: otherAttributes.put(qname, id);
150: }
151:
152: /**
153: *
154: * @return namespace uri of Keyidentifier.
155: */
156: public String getNamespaceURI() {
157: return MessageConstants.WSSE_NS;
158: }
159:
160: /**
161: * Gets the local name of this header element.
162: *
163: * @return
164: * this string must be interned.
165: */
166: public String getLocalPart() {
167: return "KeyIdentifier".intern();
168: }
169:
170: public String getAttribute(@NotNull
171: String nsUri, @NotNull
172: String localName) {
173: QName qname = new QName(nsUri, localName);
174: Map<QName, String> otherAttributes = this .getOtherAttributes();
175: return otherAttributes.get(qname);
176: }
177:
178: public String getAttribute(@NotNull
179: QName name) {
180: Map<QName, String> otherAttributes = this .getOtherAttributes();
181: return otherAttributes.get(name);
182: }
183:
184: public XMLStreamReader readHeader() throws XMLStreamException {
185: XMLStreamBufferResult xbr = new XMLStreamBufferResult();
186: JAXBElement<KeyIdentifierType> keyIdentifierElem = new ObjectFactory()
187: .createKeyIdentifier(this );
188: try {
189: getMarshaller().marshal(keyIdentifierElem, xbr);
190:
191: } catch (JAXBException je) {
192: throw new XMLStreamException(je);
193: }
194: return xbr.getXMLStreamBuffer().readAsXMLStreamReader();
195: }
196:
197: /**
198: * Writes out the header.
199: *
200: * @throws XMLStreamException
201: * if the operation fails for some reason. This leaves the
202: * writer to an undefined state.
203: */
204: public void writeTo(XMLStreamWriter streamWriter)
205: throws XMLStreamException {
206: JAXBElement<KeyIdentifierType> keyIdentifierElem = new ObjectFactory()
207: .createKeyIdentifier(this );
208: try {
209: // If writing to Zephyr, get output stream and use JAXB UTF-8 writer
210: if (streamWriter instanceof Map) {
211: OutputStream os = (OutputStream) ((Map) streamWriter)
212: .get("sjsxp-outputstream");
213: if (os != null) {
214: streamWriter.writeCharacters(""); // Force completion of open elems
215: getMarshaller().marshal(keyIdentifierElem, os);
216: return;
217: }
218: }
219:
220: getMarshaller().marshal(keyIdentifierElem, streamWriter);
221: } catch (JAXBException e) {
222: throw new XMLStreamException(e);
223: }
224: }
225:
226: /**
227: *
228: * @param streamWriter
229: * @param props
230: * @throws javax.xml.stream.XMLStreamException
231: */
232: public void writeTo(javax.xml.stream.XMLStreamWriter streamWriter,
233: HashMap props) throws javax.xml.stream.XMLStreamException {
234: try {
235: Marshaller marshaller = getMarshaller();
236: Iterator<Map.Entry<Object, Object>> itr = props.entrySet()
237: .iterator();
238: while (itr.hasNext()) {
239: Map.Entry<Object, Object> entry = itr.next();
240: marshaller.setProperty((String) entry.getKey(), entry
241: .getValue());
242: }
243: writeTo(streamWriter);
244: } catch (JAXBException jbe) {
245: throw new XMLStreamException(jbe);
246: }
247: }
248:
249: private Marshaller getMarshaller() throws JAXBException {
250: return JAXBUtil.createMarshaller(soapVersion);
251: }
252:
253: /**
254: *
255: * @param os
256: */
257: public void writeTo(OutputStream os) {
258: }
259:
260: public void updateReferenceValue(X509Certificate cert)
261: throws XWSSecurityException {
262: if (getValueType() == MessageConstants.ThumbPrintIdentifier_NS) {
263: try {
264: setReferenceValue(Base64
265: .encode(MessageDigest.getInstance("SHA-1")
266: .digest(cert.getEncoded())));
267: } catch (NoSuchAlgorithmException ex) {
268: throw new XWSSecurityException(
269: "Digest algorithm SHA-1 not found");
270: } catch (CertificateEncodingException ex) {
271: throw new XWSSecurityException(
272: "Error while getting certificate's raw content");
273: }
274: } else if (getValueType() == MessageConstants.X509SubjectKeyIdentifier_NS) {
275: byte[] subjectKeyIdentifier = cert
276: .getExtensionValue(MessageConstants.SUBJECT_KEY_IDENTIFIER_OID);
277: if (subjectKeyIdentifier == null)
278: return;
279:
280: try {
281: sun.security.x509.KeyIdentifier keyId = null;
282:
283: sun.security.util.DerValue derVal = new sun.security.util.DerValue(
284: new sun.security.util.DerInputStream(
285: subjectKeyIdentifier).getOctetString());
286:
287: keyId = new sun.security.x509.KeyIdentifier(derVal
288: .getOctetString());
289: setReferenceValue(Base64.encode(keyId.getIdentifier()));
290: } catch (NoClassDefFoundError ncde) {
291: // TODO X509 Token profile states that only the contents of the
292: // OCTET STRING should be returned, excluding the "prefix"
293: byte[] dest = new byte[subjectKeyIdentifier.length - 4];
294: System.arraycopy(subjectKeyIdentifier, 4, dest, 0,
295: subjectKeyIdentifier.length - 4);
296: setReferenceValue(Base64.encode(dest));
297:
298: } catch (IOException e) {
299: //log exception
300: throw new XWSSecurityException(
301: "Error in extracting keyIdentifier"
302: + e.getMessage());
303: }
304: }
305: }
306:
307: /**
308: *
309: * @param id
310: * @return
311: */
312: public boolean refersToSecHdrWithId(String id) {
313: String valueType = this .getValueType();
314: if (valueType
315: .equals(MessageConstants.WSSE_SAML_KEY_IDENTIFIER_VALUE_TYPE)
316: || valueType
317: .equals(MessageConstants.WSSE_SAML_v2_0_KEY_IDENTIFIER_VALUE_TYPE)) {
318: if (id.equals(this .getValue())) {
319: return true;
320: }
321: }
322: return false;
323: }
324: }
|