Skip to content

Commit

Permalink
Update CMS Version to 1 for CodeSigningCIPolicySigning
Browse files Browse the repository at this point in the history
  • Loading branch information
dhjoshi committed Jan 9, 2025
1 parent f0b0131 commit 705d94e
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions src/CodeSigning/CodeSigning/Helpers/CmsSigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public void SignCIPolicy(TokenCredential tokenCred, string accountName, string c

var signedData = cms.Encode();

UpdateCMSVersion(signedData);

if (!string.IsNullOrWhiteSpace(timeStamperUrl))
{
var timestampingUri = new Uri("http://www.microsoft.com");
Expand Down Expand Up @@ -89,5 +91,72 @@ public void SignCIPolicy(TokenCredential tokenCred, string accountName, string c
}
}
}

private byte[] UpdateCMSVersion(byte[] signedData)
{

/* Find and update CMSVersion to 1 if current version is 3.
*
* Ref: https://datatracker.ietf.org/doc/html/rfc2315
*
*
* ContentInfo ::= SEQUENCE {
* ContentType ::= OBJECT IDENTIFIER,
* Content ([0] EXPLICIT ANY DEFINED BY contentType OPTIONAL)
* SignedData ::= SEQUENCE {
version Version ::= INTEGER, // https://datatracker.ietf.org/doc/html/rfc2315#section-6.9
digestAlgorithms DigestAlgorithmIdentifiers,
contentInfo ContentInfo,
certificates
[0] IMPLICIT ExtendedCertificatesAndCertificates
OPTIONAL,
crls
[1] IMPLICIT CertificateRevocationLists OPTIONAL,
signerInfos SignerInfos } }
*
* The OID takes 11 bytes. Each other constructed element has a minimum of 2 bytes
* for tag and length, so start looking at offset 15 for a SEQUENCE followed
* immediately by INTEGER 3 (02 01 03).
*
*/

const int startOffset = 15; // Start checking from this index
const int endOffset = 100; // Stop checking at this index
const byte asn1SequenceTag = 0x30; // ASN.1 SEQUENCE tag
const byte asn1LengthBit = 0x80; // Bit indicating a constructed ASN.1 length
const byte cmsVersionTag = 0x02; // ASN.1 INTEGER tag for cmsVersion
const byte cmsVersionLength = 0x01; // CMS version value length
const byte cmsVersionV1 = 0x01; // cmsVersion 1
const byte cmsVersionV3 = 0x03; // cmsVersion 3

// Iterate over the specified range in the data
for (int i = startOffset; i < endOffset; i++)
{
// Check if the current byte marks the start of an ASN.1 SEQUENCE
if (signedData[i] == asn1SequenceTag && (signedData[i + 1] & asn1LengthBit) == asn1LengthBit)
{
// Extract the length of the SEQUENCE
int sequenceLength = signedData[i + 1] & ~asn1LengthBit; // 0x7F

// Calculate the index of the cmsVersion value
int cmsVersionIndex = i + 4 + sequenceLength;

if (cmsVersionIndex >= signedData.Length) continue;

// Verify that the structure matches the expected pattern
if (signedData[i + 2 + sequenceLength] == cmsVersionTag && // tag for cmsVersion
signedData[i + 3 + sequenceLength] == cmsVersionLength && // CMS version value length
signedData[cmsVersionIndex] == cmsVersionV3) // Version is 3, needs to be updated
{
// Update cmsVersion to 1
signedData[cmsVersionIndex] = cmsVersionV1;
return signedData; // Return the updated data
}
}
}

// Throw an exception if cmsVersion 3 was not found or could not be updated
throw new Exception("Did not find cmsVersion 3 to update.");
}
}
}

0 comments on commit 705d94e

Please sign in to comment.