1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 package org.apache.ws.security.message.token;
21
22 import org.apache.ws.security.WSConstants;
23 import org.apache.ws.security.WSSecurityException;
24 import org.apache.ws.security.components.crypto.Crypto;
25 import org.w3c.dom.Document;
26 import org.w3c.dom.Element;
27
28 import java.io.InputStream;
29 import java.io.ByteArrayInputStream;
30 import java.security.cert.CertificateEncodingException;
31 import java.security.cert.X509Certificate;
32
33 /**
34 * X509 Security Token.
35 *
36 * @author Davanum Srinivas (dims@yahoo.com).
37 */
38 public class X509Security extends BinarySecurity {
39
40 public static final String X509_V3_TYPE = WSConstants.X509TOKEN_NS + "#X509v3";
41
42 /*
43 * Stores the associated X.509 Certificate. This saves numerous
44 * crypto loadCertificate operations
45 */
46 private X509Certificate cachedCert = null;
47
48 /**
49 * This constructor creates a new X509 certificate object and initializes
50 * it from the data contained in the element.
51 *
52 * @param elem the element containing the X509 certificate data
53 * @throws WSSecurityException
54 */
55 public X509Security(Element elem) throws WSSecurityException {
56 this(elem, true);
57 }
58
59 /**
60 * This constructor creates a new X509 certificate object and initializes
61 * it from the data contained in the element.
62 *
63 * @param elem the element containing the X509 certificate data
64 * @param bspCompliant Whether the token is processed according to the BSP spec
65 * @throws WSSecurityException
66 */
67 public X509Security(Element elem, boolean bspCompliant) throws WSSecurityException {
68 super(elem, bspCompliant);
69 String valueType = getValueType();
70 if (bspCompliant && !X509_V3_TYPE.equals(valueType)) {
71 throw new WSSecurityException(
72 WSSecurityException.INVALID_SECURITY_TOKEN,
73 "invalidValueType",
74 new Object[]{valueType}
75 );
76 }
77 }
78
79 /**
80 * This constructor creates a new X509 certificate element.
81 *
82 * @param doc
83 */
84 public X509Security(Document doc) {
85 super(doc);
86 setValueType(X509_V3_TYPE);
87 }
88
89 /**
90 * Gets the X509Certificate certificate.
91 *
92 * @return the X509 certificate converted from the base 64 encoded element data
93 * @throws WSSecurityException
94 */
95 public X509Certificate getX509Certificate(Crypto crypto) throws WSSecurityException {
96 if (cachedCert != null) {
97 return cachedCert;
98 }
99 if (crypto == null) {
100 throw new WSSecurityException(WSSecurityException.FAILURE, "noSigCryptoFile");
101 }
102 byte[] data = getToken();
103 if (data == null) {
104 throw new WSSecurityException(
105 WSSecurityException.FAILURE, "invalidCertData", new Object[]{Integer.valueOf(0)}
106 );
107 }
108 InputStream in = new ByteArrayInputStream(data);
109 cachedCert = crypto.loadCertificate(in);
110 return cachedCert;
111 }
112
113 /**
114 * Sets the X509Certificate.
115 * This functions takes the X509 certificate, gets the data from it as
116 * encoded bytes, and sets the data as base 64 encoded data in the text
117 * node of the element
118 *
119 * @param cert the X509 certificate to store in the element
120 * @throws WSSecurityException
121 */
122 public void setX509Certificate(X509Certificate cert) throws WSSecurityException {
123 if (cert == null) {
124 throw new WSSecurityException(WSSecurityException.FAILURE, "noCert");
125 }
126 cachedCert = cert;
127 try {
128 setToken(cert.getEncoded());
129 } catch (CertificateEncodingException e) {
130 throw new WSSecurityException(
131 WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, "encodeError", null, e
132 );
133 }
134 }
135 }