View Javadoc
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.wss4j.common.token;
21  
22  import org.apache.wss4j.common.WSS4JConstants;
23  import org.apache.wss4j.common.bsp.BSPEnforcer;
24  import org.apache.wss4j.common.bsp.BSPRule;
25  import org.apache.wss4j.common.crypto.Crypto;
26  import org.apache.wss4j.common.crypto.Merlin;
27  import org.apache.wss4j.common.ext.WSSecurityException;
28  import org.w3c.dom.Document;
29  import org.w3c.dom.Element;
30  
31  import java.io.IOException;
32  import java.io.InputStream;
33  import java.io.ByteArrayInputStream;
34  import java.security.cert.CertificateEncodingException;
35  import java.security.cert.X509Certificate;
36  
37  /**
38   * X509 Security Token.
39   */
40  public class X509Security extends BinarySecurity {
41  
42      public static final String X509_V3_TYPE = WSS4JConstants.X509TOKEN_NS + "#X509v3";
43  
44      /*
45       * Stores the associated X.509 Certificate. This saves numerous
46       * crypto loadCertificate operations
47       */
48      private X509Certificate cachedCert;
49  
50      /**
51       * This constructor creates a new X509 certificate object and initializes
52       * it from the data contained in the element.
53       *
54       * @param elem the element containing the X509 certificate data
55       * @param bspEnforcer a BSPEnforcer instance to enforce BSP rules
56       * @throws WSSecurityException
57       */
58      public X509Security(Element elem, BSPEnforcer bspEnforcer) throws WSSecurityException {
59          super(elem, bspEnforcer);
60          String valueType = getValueType();
61          if (!X509_V3_TYPE.equals(valueType)) {
62              bspEnforcer.handleBSPRule(BSPRule.R3033);
63          }
64      }
65  
66      /**
67       * This constructor creates a new X509 certificate element.
68       *
69       * @param doc
70       */
71      public X509Security(Document doc) {
72          super(doc);
73          setValueType(X509_V3_TYPE);
74      }
75  
76      /**
77       * Gets the X509Certificate certificate.
78       *
79       * @return the X509 certificate converted from the base 64 encoded element data
80       * @throws WSSecurityException
81       */
82      public X509Certificate getX509Certificate(Crypto crypto) throws WSSecurityException {
83          if (cachedCert != null) {
84              return cachedCert;
85          }
86          Crypto certCrypto = crypto;
87          if (certCrypto == null) {
88              certCrypto = new Merlin();
89          }
90          byte[] data = getToken();
91          if (data == null) {
92              throw new WSSecurityException(
93                  WSSecurityException.ErrorCode.FAILURE, "invalidCertData", new Object[] {"0"});
94          }
95          try (InputStream in = new ByteArrayInputStream(data)) {
96              cachedCert = certCrypto.loadCertificate(in);
97              return cachedCert;
98          } catch (IOException e) {
99              throw new WSSecurityException(
100                 WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "parseError"
101             );
102         }
103 
104     }
105 
106     /**
107      * Sets the X509Certificate.
108      * This functions takes the X509 certificate, gets the data from it as
109      * encoded bytes, and sets the data as base 64 encoded data in the text
110      * node of the element
111      *
112      * @param cert the X509 certificate to store in the element
113      * @throws WSSecurityException
114      */
115     public void setX509Certificate(X509Certificate cert) throws WSSecurityException {
116         if (cert == null) {
117             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noCert");
118         }
119         cachedCert = cert;
120         try {
121             setToken(cert.getEncoded());
122         } catch (CertificateEncodingException e) {
123             throw new WSSecurityException(
124                 WSSecurityException.ErrorCode.SECURITY_TOKEN_UNAVAILABLE, e, "encodeError"
125             );
126         }
127     }
128 }