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  package org.apache.wss4j.policy.stax.assertionStates;
20  
21  import org.apache.wss4j.common.WSSPolicyException;
22  import org.apache.wss4j.policy.SPConstants;
23  import org.apache.wss4j.policy.model.AbstractSecurityAssertion;
24  import org.apache.wss4j.policy.model.AbstractToken;
25  import org.apache.wss4j.policy.model.X509Token;
26  import org.apache.wss4j.policy.stax.PolicyAsserter;
27  import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
28  import org.apache.wss4j.stax.securityEvent.X509TokenSecurityEvent;
29  import org.apache.xml.security.exceptions.XMLSecurityException;
30  import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
31  import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
32  import org.apache.xml.security.stax.securityToken.SecurityToken;
33  
34  import java.security.cert.X509Certificate;
35  
36  import javax.xml.namespace.QName;
37  
38  /**
39   * WSP1.3, 5.4.3 X509Token Assertion
40   */
41  
42  public class X509TokenAssertionState extends TokenAssertionState {
43  
44      public X509TokenAssertionState(AbstractSecurityAssertion assertion, boolean asserted,
45                                     PolicyAsserter policyAsserter, boolean initiator) {
46          super(assertion, asserted, policyAsserter, initiator);
47  
48          if (asserted) {
49              X509Token token = (X509Token) getAssertion();
50              String namespace = token.getName().getNamespaceURI();
51              if (token.isRequireKeyIdentifierReference()) {
52                  getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_KEY_IDENTIFIER_REFERENCE));
53              } else if (token.isRequireIssuerSerialReference()) {
54                  getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_ISSUER_SERIAL_REFERENCE));
55              } else if (token.isRequireEmbeddedTokenReference()) {
56                  getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_EMBEDDED_TOKEN_REFERENCE));
57              } else if (token.isRequireThumbprintReference()) {
58                  getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_THUMBPRINT_REFERENCE));
59              }
60              if (token.getTokenType() != null) {
61                  getPolicyAsserter().assertPolicy(new QName(namespace, token.getTokenType().name()));
62              }
63          }
64      }
65  
66      @Override
67      public SecurityEventConstants.Event[] getSecurityEventType() {
68          return new SecurityEventConstants.Event[]{
69                  SecurityEventConstants.X509Token
70          };
71      }
72  
73      @Override
74      public boolean assertToken(TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent,
75                                 AbstractToken abstractToken) throws WSSPolicyException, XMLSecurityException {
76          if (!(tokenSecurityEvent instanceof X509TokenSecurityEvent)) {
77              throw new WSSPolicyException("Expected a X509TokenSecurityEvent but got " + tokenSecurityEvent.getClass().getName());
78          }
79  
80          X509Token x509Token = (X509Token) abstractToken;
81  
82          SecurityToken securityToken = tokenSecurityEvent.getSecurityToken();
83          WSSecurityTokenConstants.TokenType tokenType = securityToken.getTokenType();
84          if (!(WSSecurityTokenConstants.X509V3Token.equals(tokenType)
85                  || WSSecurityTokenConstants.X509V1Token.equals(tokenType)
86                  || WSSecurityTokenConstants.X509Pkcs7Token.equals(tokenType)
87                  || WSSecurityTokenConstants.X509PkiPathV1Token.equals(tokenType))) {
88              throw new WSSPolicyException("Invalid Token for this assertion");
89          }
90  
91          try {
92              String namespace = getAssertion().getName().getNamespaceURI();
93  
94              X509Certificate x509Certificate = securityToken.getX509Certificates()[0];
95              if (x509Token.getIssuerName() != null) {
96                  final String certificateIssuerName = x509Certificate.getIssuerX500Principal().getName();
97                  if (!x509Token.getIssuerName().equals(certificateIssuerName)) {
98                      setErrorMessage("IssuerName in Policy (" + x509Token.getIssuerName()
99                          + ") didn't match with the one in the certificate (" + certificateIssuerName + ")");
100                     getPolicyAsserter().unassertPolicy(getAssertion(), getErrorMessage());
101                     return false;
102                 }
103             }
104             if (x509Token.isRequireKeyIdentifierReference()) {
105                 if (!(WSSecurityTokenConstants.KeyIdentifier_X509KeyIdentifier.equals(securityToken.getKeyIdentifier())
106                         || WSSecurityTokenConstants.KeyIdentifier_SkiKeyIdentifier.equals(securityToken.getKeyIdentifier()))) {
107                     setErrorMessage("Policy enforces KeyIdentifierReference but we got " + securityToken.getKeyIdentifier());
108                     getPolicyAsserter().unassertPolicy(new QName(namespace, SPConstants.REQUIRE_KEY_IDENTIFIER_REFERENCE),
109                                                        getErrorMessage());
110                     return false;
111                 } else {
112                     getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_KEY_IDENTIFIER_REFERENCE));
113                 }
114             } else if (x509Token.isRequireIssuerSerialReference()) {
115                 if (!WSSecurityTokenConstants.KeyIdentifier_IssuerSerial.equals(securityToken.getKeyIdentifier())) {
116                     setErrorMessage("Policy enforces IssuerSerialReference but we got " + securityToken.getKeyIdentifier());
117                     getPolicyAsserter().unassertPolicy(new QName(namespace, SPConstants.REQUIRE_ISSUER_SERIAL_REFERENCE),
118                                                      getErrorMessage());
119                     return false;
120                 } else {
121                     getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_ISSUER_SERIAL_REFERENCE));
122                 }
123             } else if (x509Token.isRequireEmbeddedTokenReference()) {
124                 if (!WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE.equals(securityToken.getKeyIdentifier())) {
125                     setErrorMessage("Policy enforces EmbeddedTokenReference but we got " + securityToken.getKeyIdentifier());
126                     getPolicyAsserter().unassertPolicy(new QName(namespace, SPConstants.REQUIRE_EMBEDDED_TOKEN_REFERENCE),
127                                                        getErrorMessage());
128                     return false;
129                 } else {
130                     getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_EMBEDDED_TOKEN_REFERENCE));
131                 }
132             } else if (x509Token.isRequireThumbprintReference()) {
133                 if (!WSSecurityTokenConstants.KEYIDENTIFIER_THUMBPRINT_IDENTIFIER.equals(securityToken.getKeyIdentifier())) {
134                     setErrorMessage("Policy enforces ThumbprintReference but we got " + securityToken.getKeyIdentifier());
135                     getPolicyAsserter().unassertPolicy(new QName(namespace, SPConstants.REQUIRE_THUMBPRINT_REFERENCE),
136                                                        getErrorMessage());
137                     return false;
138                 } else {
139                     getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_THUMBPRINT_REFERENCE));
140                 }
141             }
142             if (x509Certificate.getVersion() == 2) {
143                 setErrorMessage("X509Certificate Version " + x509Certificate.getVersion() + " not supported");
144                 getPolicyAsserter().unassertPolicy(getAssertion(), getErrorMessage());
145                 return false;
146             }
147             if (x509Token.getTokenType() != null) {
148                 switch (x509Token.getTokenType()) {
149                     case WssX509V3Token10:
150                     case WssX509V3Token11:
151                         if (!WSSecurityTokenConstants.X509V3Token.equals(securityToken.getTokenType())
152                             || x509Certificate.getVersion() != 3) {
153                             setErrorMessage("X509Certificate Version " + x509Certificate.getVersion()
154                                 + " mismatch; Policy enforces " + x509Token.getTokenType());
155                             getPolicyAsserter().unassertPolicy(new QName(namespace, x509Token.getTokenType().name()),
156                                                                          getErrorMessage());
157                             return false;
158                         }
159                         getPolicyAsserter().assertPolicy(new QName(namespace, x509Token.getTokenType().name()));
160                         break;
161                     case WssX509V1Token10:
162                     case WssX509V1Token11:
163                         if (!WSSecurityTokenConstants.X509V1Token.equals(securityToken.getTokenType())
164                             || x509Certificate.getVersion() != 1) {
165                             setErrorMessage("X509Certificate Version " + x509Certificate.getVersion()
166                                 + " mismatch; Policy enforces " + x509Token.getTokenType());
167                             getPolicyAsserter().unassertPolicy(new QName(namespace, SPConstants.WSS_X509_V1_TOKEN11),
168                                                                getErrorMessage());
169                             return false;
170                         }
171                         getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.WSS_X509_V1_TOKEN11));
172                         break;
173                     case WssX509PkiPathV1Token10:
174                     case WssX509PkiPathV1Token11:
175                         if (!WSSecurityTokenConstants.X509PkiPathV1Token.equals(securityToken.getTokenType())) {
176                             setErrorMessage("Policy enforces " + x509Token.getTokenType()
177                                 + " but we got " + securityToken.getTokenType());
178                             getPolicyAsserter().unassertPolicy(new QName(namespace, x509Token.getTokenType().name()),
179                                                                getErrorMessage());
180                             return false;
181                         }
182                         getPolicyAsserter().assertPolicy(new QName(namespace, x509Token.getTokenType().name()));
183                         break;
184                     case WssX509Pkcs7Token10:
185                     case WssX509Pkcs7Token11:
186                         setErrorMessage("Unsupported token type: " + securityToken.getTokenType());
187                         getPolicyAsserter().unassertPolicy(new QName(namespace, x509Token.getTokenType().name()),
188                                                            getErrorMessage());
189                         return false;
190                 }
191             }
192         } catch (XMLSecurityException e) {
193             setErrorMessage(e.getMessage());
194             getPolicyAsserter().unassertPolicy(getAssertion(), getErrorMessage());
195             return false;
196         }
197         //always return true to prevent false alarm in case additional tokens with the same usage
198         //appears in the message but do not fulfill the policy and are also not needed to fulfil the policy.
199         getPolicyAsserter().assertPolicy(getAssertion());
200         return true;
201     }
202 }