< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Security.SecurityTimestamp
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/SecurityTimestamp.cs
Line coverage
77%
Covered lines: 49
Uncovered lines: 14
Coverable lines: 63
Total lines: 179
Line coverage: 77.7%
Branch coverage
68%
Covered branches: 11
Total branches: 16
Branch coverage: 68.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%110%
.ctor(...)100%11100%
.ctor(...)50%2288.88%
GetDigest()100%110%
GetCreationTimeChars()100%22100%
GetExpiryTimeChars()100%22100%
ToChars(...)100%11100%
ToChars(...)100%22100%
ToString()100%110%
ValidateRangeAndFreshness(...)50%2275%
ValidateFreshness(...)50%6662.5%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/SecurityTimestamp.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Globalization;
 6using System.Xml;
 7using CoreWCF.Runtime;
 8
 9namespace CoreWCF.Security
 10{
 11    internal sealed class SecurityTimestamp
 12    {
 13        private const string DefaultFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
 014        internal static readonly TimeSpan defaultTimeToLive = SecurityProtocolFactory.defaultTimestampValidityDuration;
 15        private char[] _computedCreationTimeUtc;
 16        private char[] _computedExpiryTimeUtc;
 17        private DateTime _creationTimeUtc;
 18        private DateTime _expiryTimeUtc;
 19        private readonly byte[] _digest;
 20
 21        public SecurityTimestamp(DateTime creationTimeUtc, DateTime expiryTimeUtc, string id)
 6322            : this(creationTimeUtc, expiryTimeUtc, id, null, null)
 23        {
 6324        }
 25
 15726        internal SecurityTimestamp(DateTime creationTimeUtc, DateTime expiryTimeUtc, string id, string digestAlgorithm, 
 27        {
 28            Fx.Assert(creationTimeUtc.Kind == DateTimeKind.Utc, "creation time must be in UTC");
 29            Fx.Assert(expiryTimeUtc.Kind == DateTimeKind.Utc, "expiry time must be in UTC");
 30
 15731            if (creationTimeUtc > expiryTimeUtc)
 32            {
 033                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new ArgumentOutOfRangeException(nameof(expir
 34            }
 35
 15736            _creationTimeUtc = creationTimeUtc;
 15737            _expiryTimeUtc = expiryTimeUtc;
 15738            Id = id;
 39
 15740            DigestAlgorithm = digestAlgorithm;
 15741            _digest = digest;
 15742        }
 43
 44        public DateTime CreationTimeUtc
 45        {
 46            get
 47            {
 28248                return _creationTimeUtc;
 49            }
 50        }
 51
 52        public DateTime ExpiryTimeUtc
 53        {
 54            get
 55            {
 18856                return _expiryTimeUtc;
 57            }
 58        }
 59
 18060        public string Id { get; }
 61
 062        public string DigestAlgorithm { get; }
 63
 64        internal byte[] GetDigest()
 65        {
 066            return _digest;
 67        }
 68
 69        internal char[] GetCreationTimeChars()
 70        {
 6371            if (_computedCreationTimeUtc == null)
 72            {
 6373                _computedCreationTimeUtc = ToChars(ref _creationTimeUtc);
 74            }
 6375            return _computedCreationTimeUtc;
 76        }
 77
 78        internal char[] GetExpiryTimeChars()
 79        {
 6380            if (_computedExpiryTimeUtc == null)
 81            {
 6382                _computedExpiryTimeUtc = ToChars(ref _expiryTimeUtc);
 83            }
 6384            return _computedExpiryTimeUtc;
 85        }
 86
 87        private static char[] ToChars(ref DateTime utcTime)
 88        {
 12689            char[] buffer = new char[DefaultFormat.Length];
 12690            int offset = 0;
 91
 12692            ToChars(utcTime.Year, buffer, ref offset, 4);
 12693            buffer[offset++] = '-';
 94
 12695            ToChars(utcTime.Month, buffer, ref offset, 2);
 12696            buffer[offset++] = '-';
 97
 12698            ToChars(utcTime.Day, buffer, ref offset, 2);
 12699            buffer[offset++] = 'T';
 100
 126101            ToChars(utcTime.Hour, buffer, ref offset, 2);
 126102            buffer[offset++] = ':';
 103
 126104            ToChars(utcTime.Minute, buffer, ref offset, 2);
 126105            buffer[offset++] = ':';
 106
 126107            ToChars(utcTime.Second, buffer, ref offset, 2);
 126108            buffer[offset++] = '.';
 109
 126110            ToChars(utcTime.Millisecond, buffer, ref offset, 3);
 126111            buffer[offset++] = 'Z';
 112
 126113            return buffer;
 114        }
 115
 116        private static void ToChars(int n, char[] buffer, ref int offset, int count)
 117        {
 6048118            for (int i = offset + count - 1; i >= offset; i--)
 119            {
 2142120                buffer[i] = (char)('0' + (n % 10));
 2142121                n /= 10;
 122            }
 123            Fx.Assert(n == 0, "Overflow in encoding timestamp field");
 882124            offset += count;
 882125        }
 126
 127        public override string ToString()
 128        {
 0129            return string.Format(
 0130                CultureInfo.InvariantCulture,
 0131                "SecurityTimestamp: Id={0}, CreationTimeUtc={1}, ExpirationTimeUtc={2}",
 0132                Id,
 0133                XmlConvert.ToString(CreationTimeUtc, XmlDateTimeSerializationMode.RoundtripKind),
 0134                XmlConvert.ToString(ExpiryTimeUtc, XmlDateTimeSerializationMode.RoundtripKind));
 135        }
 136
 137        /// <summary>
 138        /// Internal method that checks if the timestamp is fresh with respect to the
 139        /// timeToLive and allowedClockSkew values passed in.
 140        /// Throws if the timestamp is stale.
 141        /// </summary>
 142        /// <param name="timeToLive"></param>
 143        /// <param name="allowedClockSkew"></param>
 144        internal void ValidateRangeAndFreshness(TimeSpan timeToLive, TimeSpan allowedClockSkew)
 145        {
 146            // Check that the creation time is less than expiry time
 94147            if (CreationTimeUtc >= ExpiryTimeUtc)
 148            {
 0149                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.Time
 150            }
 151
 94152            ValidateFreshness(timeToLive, allowedClockSkew);
 94153        }
 154
 155        internal void ValidateFreshness(TimeSpan timeToLive, TimeSpan allowedClockSkew)
 156        {
 94157            DateTime now = DateTime.UtcNow;
 158            // check that the message has not expired
 94159            if (ExpiryTimeUtc <= TimeoutHelper.Subtract(now, allowedClockSkew))
 160            {
 0161                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.Time
 162            }
 163
 164            // check that creation time is not in the future (modulo clock skew)
 94165            if (CreationTimeUtc >= TimeoutHelper.Add(now, allowedClockSkew))
 166            {
 0167                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.Time
 168            }
 169
 170            // check that the creation time is not more than timeToLive in the past
 94171            if (CreationTimeUtc <= TimeoutHelper.Subtract(now, TimeoutHelper.Add(timeToLive, allowedClockSkew)))
 172            {
 0173                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.Time
 174            }
 175
 176            // this is a fresh timestamp
 94177        }
 178    }
 179}