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.stax.validate;
20  
21  import java.time.Instant;
22  import java.time.ZonedDateTime;
23  import java.time.format.DateTimeParseException;
24  
25  import org.apache.wss4j.binding.wsu10.TimestampType;
26  import org.apache.wss4j.common.ext.WSSecurityException;
27  import org.apache.wss4j.common.util.DateUtil;
28  
29  public class TimestampValidatorImpl implements TimestampValidator {
30  
31      private static final transient org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(TimestampValidatorImpl.class);
32  
33      @Override
34      public void validate(TimestampType timestampType, TokenContext tokenContext) throws WSSecurityException {
35  
36          if (timestampType.getCreated() == null) {
37              throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, "missingCreated");
38          }
39  
40          try {
41              // Validate whether the security semantics have expired
42              //created and expires is optional per spec. But we enforce the created element in the validation
43              ZonedDateTime createdDate = null;
44              if (timestampType.getCreated() != null) {
45                  try {
46                      createdDate = ZonedDateTime.parse(timestampType.getCreated().getValue());
47                  } catch (DateTimeParseException e) {
48                      throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
49                  }
50                  LOG.debug("Timestamp created: {}", createdDate.toString());
51              }
52  
53              ZonedDateTime expiresDate = null;
54              if (timestampType.getExpires() != null) {
55                  try {
56                      expiresDate = ZonedDateTime.parse(timestampType.getExpires().getValue());
57                  } catch (DateTimeParseException e) {
58                      throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
59                  }
60                  LOG.debug("Timestamp expires: {}", expiresDate.toString());
61              } else if (tokenContext.getWssSecurityProperties().isRequireTimestampExpires()) {
62                  throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, "invalidTimestamp",
63                                                new Object[] {"The received Timestamp does not contain an expires Element"});
64              }
65  
66              int ttl = tokenContext.getWssSecurityProperties().getTimestampTTL();
67              int futureTTL = tokenContext.getWssSecurityProperties().getTimeStampFutureTTL();
68  
69              Instant rightNow = Instant.now();
70              if (expiresDate != null && tokenContext.getWssSecurityProperties().isStrictTimestampCheck()
71                  && expiresDate.toInstant().isBefore(rightNow)) {
72                  LOG.debug("Time now: {}", rightNow.toString());
73                  throw new WSSecurityException(WSSecurityException.ErrorCode.MESSAGE_EXPIRED, "invalidTimestamp",
74                                                new Object[] {"The security semantics of the message have expired"});
75              }
76  
77              if (createdDate != null && !DateUtil.verifyCreated(createdDate.toInstant(), ttl, futureTTL)) {
78                  LOG.debug("Time now: {}", rightNow.toString());
79                  throw new WSSecurityException(WSSecurityException.ErrorCode.MESSAGE_EXPIRED, "invalidTimestamp",
80                                                new Object[] {"The security semantics of the message have expired"});
81              }
82  
83          } catch (IllegalArgumentException e) {
84              throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
85          }
86      }
87  
88  }