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
24 import javax.xml.namespace.QName;
25
26 import org.apache.wss4j.common.crypto.Crypto;
27 import org.apache.wss4j.common.ext.WSSecurityException;
28 import org.apache.wss4j.common.saml.SAMLKeyInfo;
29 import org.apache.wss4j.common.saml.SAMLUtil;
30 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
31 import org.apache.wss4j.common.token.BinarySecurity;
32 import org.apache.wss4j.common.token.Reference;
33 import org.apache.wss4j.common.token.SecurityTokenReference;
34 import org.apache.wss4j.common.token.X509Security;
35 import org.apache.wss4j.common.util.XMLUtils;
36 import org.apache.wss4j.dom.WSConstants;
37 import org.apache.wss4j.dom.WSDocInfo;
38 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
39 import org.apache.wss4j.dom.handler.RequestData;
40 import org.apache.wss4j.dom.saml.WSSSAMLKeyInfoProcessor;
41 import org.w3c.dom.Element;
42
43
44
45
46
47 public class EncryptedKeySTRParser implements STRParser {
48
49
50
51
52
53
54
55
56 public STRParserResult parseSecurityTokenReference(STRParserParameters parameters) throws WSSecurityException {
57 if (parameters == null || parameters.getData() == null || parameters.getData().getWsDocInfo() == null
58 || parameters.getStrElement() == null) {
59 throw new WSSecurityException(
60 WSSecurityException.ErrorCode.FAILURE, "invalidSTRParserParameter"
61 );
62 }
63
64 SecurityTokenReference secRef =
65 new SecurityTokenReference(parameters.getStrElement(), parameters.getData().getBSPEnforcer());
66
67 String uri = null;
68 if (secRef.getReference() != null) {
69 uri = secRef.getReference().getURI();
70 uri = XMLUtils.getIDFromReference(uri);
71 } else if (secRef.containsKeyIdentifier()) {
72 uri = secRef.getKeyIdentifierValue();
73 }
74
75 WSSecurityEngineResult result = parameters.getData().getWsDocInfo().getResult(uri);
76 if (result != null) {
77 return processPreviousResult(result, secRef, parameters);
78 }
79
80 return processSTR(secRef, parameters);
81 }
82
83
84
85
86 private STRParserResult processPreviousResult(
87 WSSecurityEngineResult result,
88 SecurityTokenReference secRef,
89 STRParserParameters parameters
90 ) throws WSSecurityException {
91 STRParserResult parserResult = new STRParserResult();
92 RequestData data = parameters.getData();
93
94 Integer action = (Integer) result.get(WSSecurityEngineResult.TAG_ACTION);
95 if (action != null && WSConstants.BST == action.intValue()) {
96 BinarySecurity token =
97 (BinarySecurity)result.get(
98 WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN
99 );
100 STRParserUtil.checkBinarySecurityBSPCompliance(secRef, token, data.getBSPEnforcer());
101 X509Certificate[] certs =
102 (X509Certificate[])result.get(
103 WSSecurityEngineResult.TAG_X509_CERTIFICATES
104 );
105 parserResult.setCerts(certs);
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),
114 data.getSigVerCrypto());
115 parserResult.setCerts(keyInfo.getCerts());
116 parserResult.setPublicKey(keyInfo.getPublicKey());
117 } else {
118 throw new WSSecurityException(
119 WSSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
120 "unsupportedBinaryTokenType"
121 );
122 }
123
124 REFERENCE_TYPE referenceType = getReferenceType(secRef);
125 if (referenceType != null) {
126 parserResult.setReferenceType(referenceType);
127 }
128 return parserResult;
129 }
130
131 private STRParserResult processSTR(
132 SecurityTokenReference secRef, STRParserParameters parameters
133 ) throws WSSecurityException {
134 STRParserResult parserResult = new STRParserResult();
135 RequestData data = parameters.getData();
136 Element strElement = parameters.getStrElement();
137 WSDocInfo wsDocInfo = data.getWsDocInfo();
138 Crypto crypto = data.getDecCrypto();
139
140 if (secRef.containsKeyIdentifier()) {
141 if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())
142 || WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) {
143 SamlAssertionWrapper samlAssertion =
144 STRParserUtil.getAssertionFromKeyIdentifier(
145 secRef, strElement, data
146 );
147 STRParserUtil.checkSamlTokenBSPCompliance(secRef, samlAssertion, data.getBSPEnforcer());
148
149 SAMLKeyInfo samlKi =
150 SAMLUtil.getCredentialFromSubject(samlAssertion,
151 new WSSSAMLKeyInfoProcessor(data), data.getSigVerCrypto());
152 parserResult.setCerts(samlKi.getCerts());
153 parserResult.setPublicKey(samlKi.getPublicKey());
154 } else {
155 STRParserUtil.checkBinarySecurityBSPCompliance(secRef, null, data.getBSPEnforcer());
156 parserResult.setCerts(secRef.getKeyIdentifier(crypto));
157 }
158 } else if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {
159 parserResult.setReferenceType(REFERENCE_TYPE.ISSUER_SERIAL);
160 parserResult.setCerts(secRef.getX509IssuerSerial(crypto));
161 } else if (secRef.containsReference()) {
162 Reference reference = secRef.getReference();
163 Element bstElement =
164 STRParserUtil.getTokenElement(strElement.getOwnerDocument(), wsDocInfo, data.getCallbackHandler(),
165 reference.getURI(), reference.getValueType());
166
167
168 QName el = new QName(bstElement.getNamespaceURI(), bstElement.getLocalName());
169 if (el.equals(WSConstants.BINARY_TOKEN)) {
170 X509Security token = new X509Security(bstElement, data.getBSPEnforcer());
171 STRParserUtil.checkBinarySecurityBSPCompliance(secRef, token, data.getBSPEnforcer());
172 parserResult.setCerts(new X509Certificate[]{token.getX509Certificate(crypto)});
173 } else {
174 throw new WSSecurityException(
175 WSSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN,
176 "unsupportedBinaryTokenType"
177 );
178 }
179 }
180
181 REFERENCE_TYPE referenceType = getReferenceType(secRef);
182 if (referenceType != null) {
183 parserResult.setReferenceType(referenceType);
184 }
185
186 return parserResult;
187 }
188
189 private REFERENCE_TYPE getReferenceType(SecurityTokenReference secRef) {
190 if (secRef.containsReference()) {
191 return REFERENCE_TYPE.DIRECT_REF;
192 } else if (secRef.containsKeyIdentifier()) {
193 if (SecurityTokenReference.THUMB_URI.equals(secRef.getKeyIdentifierValueType())) {
194 return REFERENCE_TYPE.THUMBPRINT_SHA1;
195 } else {
196 return REFERENCE_TYPE.KEY_IDENTIFIER;
197 }
198 }
199
200 return null;
201 }
202 }