1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.dom.str;
21
22 import java.security.cert.X509Certificate;
23 import java.util.Arrays;
24 import java.util.List;
25
26 import org.apache.wss4j.common.crypto.Crypto;
27 import org.apache.wss4j.common.ext.WSPasswordCallback;
28 import org.apache.wss4j.common.ext.WSSecurityException;
29 import org.apache.wss4j.common.saml.SAMLKeyInfo;
30 import org.apache.wss4j.common.saml.SAMLUtil;
31 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
32 import org.apache.wss4j.common.token.BinarySecurity;
33 import org.apache.wss4j.common.token.SecurityTokenReference;
34 import org.apache.wss4j.common.util.KeyUtils;
35 import org.apache.wss4j.common.util.XMLUtils;
36 import org.apache.wss4j.dom.WSConstants;
37 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
38 import org.apache.wss4j.dom.handler.RequestData;
39 import org.apache.wss4j.dom.saml.WSSSAMLKeyInfoProcessor;
40
41
42
43
44
45 public class DerivedKeyTokenSTRParser implements STRParser {
46
47
48
49
50
51
52
53
54 public STRParserResult parseSecurityTokenReference(STRParserParameters parameters) throws WSSecurityException {
55
56 if (parameters == null || parameters.getData() == null || parameters.getData().getWsDocInfo() == null
57 || parameters.getStrElement() == null) {
58 throw new WSSecurityException(
59 WSSecurityException.ErrorCode.FAILURE, "invalidSTRParserParameter"
60 );
61 }
62
63 SecurityTokenReference secRef =
64 new SecurityTokenReference(parameters.getStrElement(), parameters.getData().getBSPEnforcer());
65
66 String uri = null;
67 if (secRef.getReference() != null) {
68 uri = secRef.getReference().getURI();
69 uri = XMLUtils.getIDFromReference(uri);
70 } else if (secRef.containsKeyIdentifier()) {
71 uri = secRef.getKeyIdentifierValue();
72 }
73
74 WSSecurityEngineResult result = parameters.getData().getWsDocInfo().getResult(uri);
75 if (result != null) {
76 return processPreviousResult(result, secRef, parameters);
77 }
78
79 return processSTR(secRef, uri, parameters);
80 }
81
82
83
84
85 private STRParserResult processPreviousResult(
86 WSSecurityEngineResult result,
87 SecurityTokenReference secRef,
88 STRParserParameters parameters
89 ) throws WSSecurityException {
90 STRParserResult parserResult = new STRParserResult();
91 RequestData data = parameters.getData();
92
93 Integer action = (Integer)result.get(WSSecurityEngineResult.TAG_ACTION);
94 if (action != null
95 && (WSConstants.UT_NOPASSWORD == action.intValue() || WSConstants.UT == action.intValue())) {
96 STRParserUtil.checkUsernameTokenBSPCompliance(secRef, data.getBSPEnforcer());
97 byte[] secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
98 parserResult.setSecretKey(secretKey);
99 } else if (action != null && WSConstants.ENCR == action.intValue()) {
100 STRParserUtil.checkEncryptedKeyBSPCompliance(secRef, data.getBSPEnforcer());
101 byte[] secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
102 parserResult.setSecretKey(secretKey);
103 } else if (action != null && (WSConstants.SCT == action.intValue() || WSConstants.BST == action.intValue())) {
104 byte[] secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
105 parserResult.setSecretKey(secretKey);
106 } else if (action != null
107 && (WSConstants.ST_UNSIGNED == action.intValue() || WSConstants.ST_SIGNED == action.intValue())) {
108 SamlAssertionWrapper samlAssertion =
109 (SamlAssertionWrapper)result.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
110 STRParserUtil.checkSamlTokenBSPCompliance(secRef, samlAssertion, data.getBSPEnforcer());
111
112 SAMLKeyInfo keyInfo =
113 SAMLUtil.getCredentialFromSubject(samlAssertion, new WSSSAMLKeyInfoProcessor(data), data.getSigVerCrypto());
114
115
116 byte[] secretKey = keyInfo.getSecret();
117 parserResult.setSecretKey(secretKey);
118 } else {
119 throw new WSSecurityException(
120 WSSecurityException.ErrorCode.FAILED_CHECK, "unsupportedKeyId"
121 );
122 }
123
124 return parserResult;
125 }
126
127 private STRParserResult processSTR(
128 SecurityTokenReference secRef,
129 String uri,
130 STRParserParameters parameters
131 ) throws WSSecurityException {
132 STRParserResult parserResult = new STRParserResult();
133 RequestData data = parameters.getData();
134
135 if (secRef.containsReference()) {
136
137 byte[] secretKey =
138 STRParserUtil.getSecretKeyFromToken(uri, null, WSPasswordCallback.SECURITY_CONTEXT_TOKEN, data);
139 if (secretKey == null || secretKey.length == 0) {
140 throw new WSSecurityException(
141 WSSecurityException.ErrorCode.FAILED_CHECK, "unsupportedKeyId",
142 new Object[] {uri});
143 }
144 parserResult.setSecretKey(secretKey);
145 } else if (secRef.containsKeyIdentifier()) {
146 String keyIdentifierValueType = secRef.getKeyIdentifierValueType();
147 if (WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(keyIdentifierValueType)) {
148 byte[] secretKey =
149 STRParserUtil.getSecretKeyFromToken(
150 secRef.getKeyIdentifierValue(), keyIdentifierValueType,
151 WSPasswordCallback.SECRET_KEY, data
152 );
153 if (secretKey == null || secretKey.length == 0) {
154 byte[] keyBytes = secRef.getSKIBytes();
155 List<WSSecurityEngineResult> resultsList =
156 data.getWsDocInfo().getResultsByTag(WSConstants.BST);
157 for (WSSecurityEngineResult bstResult : resultsList) {
158 BinarySecurity bstToken =
159 (BinarySecurity)bstResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
160 byte[] tokenDigest = KeyUtils.generateDigest(bstToken.getToken());
161 if (Arrays.equals(tokenDigest, keyBytes)) {
162 secretKey = (byte[])bstResult.get(WSSecurityEngineResult.TAG_SECRET);
163 break;
164 }
165 }
166 }
167 if (secretKey == null) {
168 throw new WSSecurityException(
169 WSSecurityException.ErrorCode.FAILED_CHECK, "unsupportedKeyId",
170 new Object[] {uri});
171 }
172 parserResult.setSecretKey(secretKey);
173 } else {
174 if (SecurityTokenReference.ENC_KEY_SHA1_URI.equals(keyIdentifierValueType)) {
175 STRParserUtil.checkEncryptedKeyBSPCompliance(secRef, data.getBSPEnforcer());
176 }
177 Crypto crypto = data.getDecCrypto();
178 X509Certificate[] certs = secRef.getKeyIdentifier(crypto);
179 if (certs == null || certs.length < 1 || certs[0] == null) {
180 byte[] secretKey =
181 STRParserUtil.getSecretKeyFromToken(
182 secRef.getKeyIdentifierValue(), keyIdentifierValueType,
183 WSPasswordCallback.SECRET_KEY, data
184 );
185 if (secretKey == null || secretKey.length == 0) {
186 throw new WSSecurityException(
187 WSSecurityException.ErrorCode.FAILED_CHECK, "unsupportedKeyId",
188 new Object[] {uri});
189 }
190 parserResult.setSecretKey(secretKey);
191 } else {
192 byte[] secretKey = crypto.getPrivateKey(certs[0], data.getCallbackHandler()).getEncoded();
193 parserResult.setSecretKey(secretKey);
194 }
195 }
196 } else {
197 throw new WSSecurityException(
198 WSSecurityException.ErrorCode.FAILED_CHECK, "unsupportedKeyId"
199 );
200 }
201
202 return parserResult;
203 }
204
205 }