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.dom.util;
21  
22  import org.apache.wss4j.dom.WSConstants;
23  import org.apache.wss4j.common.ext.WSPasswordCallback;
24  import org.apache.wss4j.common.ext.WSSecurityException;
25  import org.apache.wss4j.common.util.XMLUtils;
26  import org.w3c.dom.Element;
27  import org.w3c.dom.Node;
28  
29  import javax.security.auth.callback.Callback;
30  import javax.security.auth.callback.CallbackHandler;
31  import javax.security.auth.callback.UnsupportedCallbackException;
32  import javax.xml.crypto.MarshalException;
33  import javax.xml.crypto.XMLStructure;
34  import javax.xml.crypto.dom.DOMStructure;
35  import javax.xml.crypto.dsig.XMLSignatureFactory;
36  import javax.xml.crypto.dsig.keyinfo.KeyInfo;
37  import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
38  import javax.xml.crypto.dsig.keyinfo.KeyValue;
39  
40  import java.io.IOException;
41  import java.security.PublicKey;
42  import java.util.List;
43  
44  public final class X509Util {
45      private static final org.slf4j.Logger LOG =
46          org.slf4j.LoggerFactory.getLogger(X509Util.class);
47  
48      private X509Util() {
49          // Complete
50      }
51  
52      public static boolean isContent(Node encBodyData) {
53          if (encBodyData != null) {
54              String typeStr = ((Element)encBodyData).getAttributeNS(null, "Type");
55              if (typeStr != null) {
56                   return typeStr.equals(WSConstants.ENC_NS + "Content");
57              }
58          }
59          return false;
60      }
61  
62      public static String getEncAlgo(Node encBodyData) throws WSSecurityException {
63          Element tmpE =
64              XMLUtils.getDirectChildElement(
65                  encBodyData, "EncryptionMethod", WSConstants.ENC_NS
66              );
67          String symEncAlgo = null;
68          if (tmpE != null) {
69              symEncAlgo = tmpE.getAttributeNS(null, "Algorithm");
70              if (symEncAlgo == null || symEncAlgo.length() == 0) {
71                  throw new WSSecurityException(
72                      WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, "noEncAlgo"
73                  );
74              }
75          }
76          LOG.debug("Sym Enc Algo: {}", symEncAlgo);
77          return symEncAlgo;
78      }
79  
80      public static byte[] getSecretKey(
81          Element keyInfoElem,
82          String algorithm,
83          CallbackHandler cb
84      ) throws WSSecurityException {
85          String keyName = null;
86          Element keyNmElem =
87              XMLUtils.getDirectChildElement(
88                  keyInfoElem, "KeyName", WSConstants.SIG_NS
89              );
90          if (keyNmElem != null) {
91              keyName = XMLUtils.getElementText(keyNmElem);
92          }
93          if (keyName == null || keyName.length() <= 0) {
94              LOG.debug("No Key Name available");
95          }
96          WSPasswordCallback pwCb = new WSPasswordCallback(keyName, WSPasswordCallback.SECRET_KEY);
97          pwCb.setAlgorithm(algorithm);
98          try {
99              cb.handle(new Callback[]{pwCb});
100         } catch (IOException | UnsupportedCallbackException e) {
101             throw new WSSecurityException(
102                 WSSecurityException.ErrorCode.FAILURE, e,
103                 "noPassword",
104                 new Object[] {keyName});
105         }
106         byte[] decryptedData = pwCb.getKey();
107         if (decryptedData == null) {
108             throw new WSSecurityException(
109                 WSSecurityException.ErrorCode.FAILURE,
110                 "noPassword",
111                 new Object[] {keyName});
112         }
113         return decryptedData;
114     }
115 
116     public static PublicKey parseKeyValue(Element keyInfoElement,
117                                           XMLSignatureFactory signatureFactory) throws WSSecurityException {
118         KeyValue keyValue = null;
119         try {
120             //
121             // Look for a KeyValue object
122             //
123             keyValue = getKeyValue(keyInfoElement, signatureFactory);
124         } catch (MarshalException ex) {
125             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
126         }
127 
128         if (keyValue != null) {
129             try {
130                 //
131                 // Look for a Public Key in Key Value
132                 //
133                 return keyValue.getPublicKey();
134             } catch (java.security.KeyException ex) {
135                 LOG.error(ex.getMessage(), ex);
136                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
137             }
138         } else {
139             throw new WSSecurityException(
140                 WSSecurityException.ErrorCode.INVALID_SECURITY, "unsupportedKeyInfo"
141             );
142         }
143     }
144 
145     /**
146      * Get the KeyValue object from the KeyInfo DOM element if it exists
147      */
148     public static KeyValue getKeyValue(Element keyInfoElement,
149                                        XMLSignatureFactory signatureFactory) throws MarshalException {
150         XMLStructure keyInfoStructure = new DOMStructure(keyInfoElement);
151         KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
152         KeyInfo keyInfo = keyInfoFactory.unmarshalKeyInfo(keyInfoStructure);
153         List<?> list = keyInfo.getContent();
154 
155         for (Object obj : list) {
156             XMLStructure xmlStructure = (XMLStructure) obj;
157             if (xmlStructure instanceof KeyValue) {
158                 return (KeyValue)xmlStructure;
159             }
160         }
161         return null;
162     }
163 
164 
165 }