diff --git a/src/Tasks/ManifestUtil/mansign2.cs b/src/Tasks/ManifestUtil/mansign2.cs index da2308866d1..dfc7d8e46c2 100644 --- a/src/Tasks/ManifestUtil/mansign2.cs +++ b/src/Tasks/ManifestUtil/mansign2.cs @@ -814,13 +814,28 @@ private static string ObtainRFC3161Timestamp(string timeStampUrl, string signatu try { - byte[] nonce = new byte[24]; + byte[] nonce = new byte[32]; using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) { rng.GetBytes(nonce); } + // Eventually, CryptEncodeObjectEx(...) is called on a CRYPT_TIMESTAMP_REQUEST with this nonce, + // and CryptEncodeObjectEx(...) interprets the nonce as a little endian, DER-encoded integer value + // (without tag and length), and may even strip leading bytes from the big endian representation + // of the byte sequence to achieve proper integer DER encoding. + // + // If the nonce is changed after the client generates it, the timestamp server would receive + // and return a nonce that does not agree with the client's original nonce. + // + // To ensure this does not happen, ensure that the most significant byte in the little + // endian byte sequence is in the 0x01-0x7F range; clear that byte's most significant bit + // and set that byte's least significant bit. + + nonce[nonce.Length - 1] &= 0x7f; + nonce[nonce.Length - 1] |= 0x01; + Win32.CRYPT_TIMESTAMP_PARA para = new Win32.CRYPT_TIMESTAMP_PARA() { fRequestCerts = true,