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.securityToken;
20
21 import java.security.Key;
22 import java.security.Principal;
23 import java.security.cert.X509Certificate;
24 import java.util.Collection;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27
28 import javax.security.auth.Subject;
29 import javax.security.auth.callback.CallbackHandler;
30
31 import org.apache.wss4j.common.crypto.Crypto;
32 import org.apache.wss4j.common.crypto.CryptoType;
33 import org.apache.wss4j.common.ext.WSPasswordCallback;
34 import org.apache.wss4j.common.ext.WSSecurityException;
35 import org.apache.wss4j.common.principal.PublicKeyPrincipalImpl;
36 import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
37 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
38 import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
39 import org.apache.wss4j.stax.securityToken.X509SecurityToken;
40 import org.apache.wss4j.stax.utils.WSSUtils;
41 import org.apache.xml.security.exceptions.XMLSecurityException;
42 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
43 import org.apache.xml.security.stax.securityToken.SecurityTokenConstants.TokenType;
44
45 public abstract class X509SecurityTokenImpl
46 extends org.apache.xml.security.stax.impl.securityToken.X509SecurityToken implements X509SecurityToken {
47
48 private static final transient org.slf4j.Logger LOG =
49 org.slf4j.LoggerFactory.getLogger(X509SecurityTokenImpl.class);
50
51 private CallbackHandler callbackHandler;
52 private Crypto crypto;
53 private WSSSecurityProperties securityProperties;
54 private Principal principal;
55
56 protected X509SecurityTokenImpl(
57 WSSecurityTokenConstants.TokenType tokenType, WSInboundSecurityContext wsInboundSecurityContext,
58 Crypto crypto, CallbackHandler callbackHandler, String id,
59 WSSecurityTokenConstants.KeyIdentifier keyIdentifier, WSSSecurityProperties securityProperties,
60 boolean includedInMessage) {
61 super(tokenType, wsInboundSecurityContext, id, keyIdentifier, includedInMessage);
62 this.crypto = crypto;
63 this.callbackHandler = callbackHandler;
64 this.securityProperties = securityProperties;
65 }
66
67 protected Crypto getCrypto() {
68 return crypto;
69 }
70
71 protected void setCrypto(Crypto crypto) {
72 this.crypto = crypto;
73 }
74
75 public CallbackHandler getCallbackHandler() {
76 return callbackHandler;
77 }
78
79 @Override
80 public Key getKey(String algorithmURI, XMLSecurityConstants.AlgorithmUsage algorithmUsage,
81 String correlationID) throws XMLSecurityException {
82 WSPasswordCallback pwCb = new WSPasswordCallback(getAlias(), WSPasswordCallback.DECRYPT);
83 WSSUtils.doPasswordCallback(getCallbackHandler(), pwCb);
84 try {
85 return getCrypto().getPrivateKey(getAlias(), pwCb.getPassword());
86 } catch (WSSecurityException ex) {
87
88 Crypto decCrypto = securityProperties.getDecryptionCrypto();
89 if (decCrypto != null && decCrypto != getCrypto()) {
90 return decCrypto.getPrivateKey(getAlias(), pwCb.getPassword());
91 }
92 throw ex;
93 }
94 }
95
96 @Override
97 public X509Certificate[] getX509Certificates() throws XMLSecurityException {
98 if (super.getX509Certificates() == null) {
99 String alias = getAlias();
100 if (alias != null) {
101 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
102 cryptoType.setAlias(alias);
103 setX509Certificates(getCrypto().getX509Certificates(cryptoType));
104 }
105 }
106 return super.getX509Certificates();
107 }
108
109 @Override
110 public void verify() throws XMLSecurityException {
111
112 X509Certificate[] x509Certificates = getX509Certificates();
113 if (x509Certificates != null && x509Certificates.length > 0) {
114 boolean enableRevocation = false;
115 Collection<Pattern> subjectCertConstraints = null;
116 Collection<Pattern> issuerCertConstraints = null;
117 if (securityProperties != null) {
118 enableRevocation = securityProperties.isEnableRevocation();
119 subjectCertConstraints = securityProperties.getSubjectCertConstraints();
120 issuerCertConstraints = securityProperties.getIssuerDNConstraints();
121 }
122 getCrypto().verifyTrust(x509Certificates, enableRevocation, subjectCertConstraints, issuerCertConstraints);
123 }
124 }
125
126
127
128
129
130
131 protected boolean
132 matches(
133 final X509Certificate cert, final Collection<Pattern> subjectDNPatterns
134 ) {
135 if (subjectDNPatterns.isEmpty()) {
136 LOG.warn("No Subject DN Certificate Constraints were defined. This could be a security issue");
137 }
138 if (!subjectDNPatterns.isEmpty()) {
139 if (cert == null) {
140 LOG.debug("The certificate is null so no constraints matching was possible");
141 return false;
142 }
143 String subjectName = cert.getSubjectX500Principal().getName();
144 boolean subjectMatch = false;
145 for (Pattern subjectDNPattern : subjectDNPatterns) {
146 final Matcher matcher = subjectDNPattern.matcher(subjectName);
147 if (matcher.matches()) {
148 LOG.debug("Subject DN {} matches with pattern {}", subjectName, subjectDNPattern);
149 subjectMatch = true;
150 break;
151 }
152 }
153 if (!subjectMatch) {
154 return false;
155 }
156 }
157
158 return true;
159 }
160
161 protected abstract String getAlias() throws XMLSecurityException;
162
163 @Override
164 public Subject getSubject() throws WSSecurityException {
165 return null;
166 }
167
168 @Override
169 public Principal getPrincipal() throws WSSecurityException {
170 if (this.principal == null) {
171 try {
172 X509Certificate[] certs = getX509Certificates();
173 if (certs != null && certs.length > 0) {
174 return this.principal = certs[0].getSubjectX500Principal();
175 }
176 return this.principal = new PublicKeyPrincipalImpl(getPublicKey());
177 } catch (XMLSecurityException e) {
178 throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, e);
179 }
180 }
181 return this.principal;
182 }
183
184 @Override
185 public TokenType getTokenType() {
186 TokenType storedTokenType = super.getTokenType();
187
188 if (WSSecurityTokenConstants.X509V3Token.equals(storedTokenType)) {
189 try {
190 X509Certificate[] certs = super.getX509Certificates();
191 if (certs != null && certs.length > 0 && certs[0].getVersion() == 1) {
192 return WSSecurityTokenConstants.X509V1Token;
193 }
194 } catch (XMLSecurityException e) {
195 return storedTokenType;
196 }
197 }
198
199 return storedTokenType;
200
201
202 }
203 }