| File: Signing\DerEncoding\DerGeneralizedTime.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Packaging\NuGet.Packaging.csproj (NuGet.Packaging) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Globalization; using System.Security.Cryptography; namespace NuGet.Packaging.Signing.DerEncoding { /// <remarks>This is public only to facilitate testing.</remarks> public sealed class DerGeneralizedTime { public DateTime DateTime { get; } private DerGeneralizedTime(DateTime datetime) { DateTime = datetime; } public static DerGeneralizedTime Read(string decodedTime) { // YYYYMMDDhhmmssZ var minimumValidLength = 15; if (string.IsNullOrEmpty(decodedTime) || decodedTime.Length < minimumValidLength) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } if (decodedTime[decodedTime.Length - 1] != 'Z') { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } #if NETCOREAPP var decimalIndex = decodedTime.IndexOf('.', StringComparison.Ordinal); #else var decimalIndex = decodedTime.IndexOf('.'); #endif var stringToParse = decodedTime; string format; if (decimalIndex == -1) { format = "yyyyMMddHHmmssZ"; } else { // 20180214095812.3456789Z // ^-----^ var fractionalSecondDigits = decodedTime.Length - 2 - decimalIndex; // Disallow decimal with no following digits if (fractionalSecondDigits < 1) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } // Disallow trailing zero if (decodedTime[decodedTime.Length - 2] == '0') { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } if (fractionalSecondDigits > 7) { // DateTime is precise to 1 ten-millionth of a second or 7 digits after the decimal. // If decodedTime precision is greater than this, ignore the trailing digits. // The length of the maximum format string minus the trailing "Z" is 22 characters: // // 20180214095812.3456789Z // ^--------------------^ stringToParse = $"{decodedTime.Substring(0, 22)}Z"; fractionalSecondDigits = 7; } format = $"yyyyMMddHHmmss.{new string('F', fractionalSecondDigits)}Z"; } DateTime datetime; if (DateTime.TryParseExact( stringToParse, format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out datetime)) { return new DerGeneralizedTime(datetime); } throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } } }