1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.stax.impl.processor.input;
20
21 import java.math.BigInteger;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import org.apache.wss4j.binding.wss10.SecurityTokenReferenceType;
26 import org.apache.wss4j.common.bsp.BSPRule;
27 import org.apache.wss4j.common.ext.WSSecurityException;
28 import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
29 import org.apache.wss4j.stax.ext.WSSConstants;
30 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
31 import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
32 import org.apache.wss4j.stax.utils.WSSUtils;
33 import org.apache.wss4j.stax.validate.SignatureTokenValidator;
34 import org.apache.wss4j.stax.validate.SignatureTokenValidatorImpl;
35 import org.apache.xml.security.binding.excc14n.InclusiveNamespaces;
36 import org.apache.xml.security.binding.xmldsig.CanonicalizationMethodType;
37 import org.apache.xml.security.binding.xmldsig.ManifestType;
38 import org.apache.xml.security.binding.xmldsig.ObjectType;
39 import org.apache.xml.security.binding.xmldsig.SignatureType;
40 import org.apache.xml.security.exceptions.XMLSecurityException;
41 import org.apache.xml.security.stax.ext.InboundSecurityContext;
42 import org.apache.xml.security.stax.ext.InputProcessorChain;
43 import org.apache.xml.security.stax.ext.XMLSecurityProperties;
44 import org.apache.xml.security.stax.ext.XMLSecurityUtils;
45 import org.apache.xml.security.stax.impl.processor.input.AbstractSignatureInputHandler;
46 import org.apache.xml.security.stax.securityEvent.AlgorithmSuiteSecurityEvent;
47 import org.apache.xml.security.stax.securityEvent.SignatureValueSecurityEvent;
48 import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
49 import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
50 import org.apache.xml.security.stax.securityToken.SecurityToken;
51 import org.apache.xml.security.stax.securityToken.SecurityTokenFactory;
52
53 public class WSSSignatureInputHandler extends AbstractSignatureInputHandler {
54
55 private static final transient org.slf4j.Logger LOG =
56 org.slf4j.LoggerFactory.getLogger(WSSSignatureInputHandler.class);
57
58 @Override
59 protected SignatureVerifier newSignatureVerifier(
60 final InputProcessorChain inputProcessorChain, final XMLSecurityProperties securityProperties,
61 final SignatureType signatureType) throws XMLSecurityException {
62
63 if (signatureType.getKeyInfo() == null) {
64 throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
65 }
66 checkBSPCompliance(inputProcessorChain, signatureType);
67
68 String algorithm = signatureType.getSignedInfo().getSignatureMethod().getAlgorithm();
69 if (securityProperties.getSignatureAlgorithm() != null
70 && !securityProperties.getSignatureAlgorithm().equals(algorithm)) {
71 LOG.warn(
72 "The Signature method does not match the requirement"
73 );
74 throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
75 }
76
77 final WSInboundSecurityContext securityContext = (WSInboundSecurityContext) inputProcessorChain.getSecurityContext();
78
79 SignatureValueSecurityEvent signatureValueSecurityEvent = new SignatureValueSecurityEvent();
80 signatureValueSecurityEvent.setSignatureValue(signatureType.getSignatureValue().getValue());
81 signatureValueSecurityEvent.setCorrelationID(signatureType.getId());
82 securityContext.registerSecurityEvent(signatureValueSecurityEvent);
83
84 AlgorithmSuiteSecurityEvent algorithmSuiteSecurityEvent = new AlgorithmSuiteSecurityEvent();
85 algorithmSuiteSecurityEvent.setAlgorithmURI(signatureType.getSignedInfo().getCanonicalizationMethod().getAlgorithm());
86 algorithmSuiteSecurityEvent.setAlgorithmUsage(WSSConstants.SigC14n);
87 algorithmSuiteSecurityEvent.setCorrelationID(signatureType.getId());
88 securityContext.registerSecurityEvent(algorithmSuiteSecurityEvent);
89
90 return new WSSSignatureVerifier(signatureType, inputProcessorChain.getSecurityContext(), securityProperties);
91 }
92
93 private void checkBSPCompliance(InputProcessorChain inputProcessorChain, SignatureType signatureType) throws WSSecurityException {
94 String algorithm = signatureType.getSignedInfo().getSignatureMethod().getAlgorithm();
95 final WSInboundSecurityContext securityContext = (WSInboundSecurityContext) inputProcessorChain.getSecurityContext();
96 if (!(WSSConstants.NS_XMLDSIG_HMACSHA1.equals(algorithm)
97 || WSSConstants.NS_XMLDSIG_RSASHA1.equals(algorithm)
98 || WSSConstants.NS_XMLDSIG_HMACSHA256.equals(algorithm)
99 || WSSConstants.NS_XMLDSIG_HMACSHA384.equals(algorithm)
100 || WSSConstants.NS_XMLDSIG_HMACSHA512.equals(algorithm)
101 || WSSConstants.NS_XMLDSIG_RSASHA256.equals(algorithm)
102 || WSSConstants.NS_XMLDSIG_RSASHA384.equals(algorithm)
103 || WSSConstants.NS_XMLDSIG_RSASHA512.equals(algorithm))) {
104
105 securityContext.handleBSPRule(BSPRule.R5421);
106 }
107
108 BigInteger hmacOutputLength = XMLSecurityUtils.getQNameType(
109 signatureType.getSignedInfo().getSignatureMethod().getContent(),
110 WSSConstants.TAG_dsig_HMACOutputLength);
111 if (hmacOutputLength != null) {
112 securityContext.handleBSPRule(BSPRule.R5401);
113 }
114
115 List<Object> keyInfoContent = signatureType.getKeyInfo().getContent();
116 if (keyInfoContent.size() != 1) {
117 securityContext.handleBSPRule(BSPRule.R5402);
118 }
119
120 SecurityTokenReferenceType securityTokenReferenceType = XMLSecurityUtils.getQNameType(keyInfoContent,
121 WSSConstants.TAG_WSSE_SECURITY_TOKEN_REFERENCE);
122 if (securityTokenReferenceType == null) {
123 securityContext.handleBSPRule(BSPRule.R5417);
124 }
125
126 Iterator<ObjectType> objectTypeIterator = signatureType.getObject().iterator();
127 while (objectTypeIterator.hasNext()) {
128 ObjectType objectType = objectTypeIterator.next();
129 ManifestType manifestType = XMLSecurityUtils.getQNameType(objectType.getContent(), WSSConstants.TAG_dsig_Manifest);
130 if (manifestType != null) {
131 securityContext.handleBSPRule(BSPRule.R5403);
132 }
133 }
134
135 CanonicalizationMethodType canonicalizationMethodType = signatureType.getSignedInfo().getCanonicalizationMethod();
136 if (!WSSConstants.NS_C14N_EXCL.equals(canonicalizationMethodType.getAlgorithm())) {
137 securityContext.handleBSPRule(BSPRule.R5404);
138 }
139
140 InclusiveNamespaces inclusiveNamespacesType = XMLSecurityUtils.getQNameType(canonicalizationMethodType.getContent(),
141 WSSConstants.TAG_c14nExcl_InclusiveNamespaces);
142 if (inclusiveNamespacesType != null && inclusiveNamespacesType.getPrefixList().isEmpty()) {
143 securityContext.handleBSPRule(BSPRule.R5406);
144 }
145 }
146
147 @Override
148 protected void addSignatureReferenceInputProcessorToChain(
149 InputProcessorChain inputProcessorChain, XMLSecurityProperties securityProperties,
150 SignatureType signatureType, InboundSecurityToken inboundSecurityToken) throws XMLSecurityException {
151
152
153 inputProcessorChain.addProcessor(
154 new WSSSignatureReferenceVerifyInputProcessor(inputProcessorChain, signatureType,
155 inboundSecurityToken, securityProperties));
156 }
157
158 public class WSSSignatureVerifier extends SignatureVerifier {
159
160 public WSSSignatureVerifier(SignatureType signatureType, InboundSecurityContext inboundSecurityContext,
161 XMLSecurityProperties securityProperties) throws XMLSecurityException {
162 super(signatureType, inboundSecurityContext, securityProperties);
163 }
164
165 @Override
166 protected InboundSecurityToken retrieveSecurityToken(SignatureType signatureType,
167 XMLSecurityProperties securityProperties,
168 InboundSecurityContext inboundSecurityContext) throws XMLSecurityException {
169
170 InboundSecurityToken inboundSecurityToken = SecurityTokenFactory.getInstance().getSecurityToken(
171 signatureType.getKeyInfo(), WSSecurityTokenConstants.KeyUsage_Signature_Verification,
172 securityProperties, inboundSecurityContext);
173
174 SignatureTokenValidator signatureTokenValidator =
175 ((WSSSecurityProperties) securityProperties).getValidator(WSSConstants.TAG_dsig_Signature);
176 if (signatureTokenValidator == null) {
177 signatureTokenValidator = new SignatureTokenValidatorImpl();
178 }
179 signatureTokenValidator.validate(inboundSecurityToken, (WSSSecurityProperties) securityProperties);
180
181
182 inboundSecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_Signature);
183 TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent
184 = WSSUtils.createTokenSecurityEvent(inboundSecurityToken, signatureType.getId());
185 inboundSecurityContext.registerSecurityEvent(tokenSecurityEvent);
186
187 return inboundSecurityToken;
188 }
189 }
190 }