Example #1
0
        private static byte[] EncodePayloadContents(SignaturePayload signaturePayload)
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    // Write the version
                    writer.Write((byte)0x02); // Tag = INTEGER
                    writer.Write((byte)0x01); // Length
                    writer.Write((byte)signaturePayload.Version); // Value

                    // Write the content identifier
                    var strBytes = Encoding.UTF8.GetBytes(signaturePayload.ContentIdentifier);
                    writer.Write((byte)0x0C); // Tag = UTF8String
                    WriteLength(writer, strBytes.Length); // Length
                    writer.Write(strBytes);

                    // Write the digest value
                    byte[] digestValue = EncodeDigestValue(signaturePayload);

                    writer.Write((byte)0x30); // Tag = SEQUENCE
                    WriteLength(writer, digestValue.Length); // Length
                    writer.Write(digestValue); // Value
                }
                return stream.ToArray();
            }
        }
Example #2
0
        private static byte[] EncodePayloadContents(SignaturePayload signaturePayload)
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    // Write the version
                    writer.Write((byte)0x02);                     // Tag = INTEGER
                    writer.Write((byte)0x01);                     // Length
                    writer.Write((byte)signaturePayload.Version); // Value

                    // Write the content identifier
                    var strBytes = Encoding.UTF8.GetBytes(signaturePayload.ContentIdentifier);
                    writer.Write((byte)0x0C);             // Tag = UTF8String
                    WriteLength(writer, strBytes.Length); // Length
                    writer.Write(strBytes);

                    // Write the digest value
                    byte[] digestValue = EncodeDigestValue(signaturePayload);

                    writer.Write((byte)0x30);                // Tag = SEQUENCE
                    WriteLength(writer, digestValue.Length); // Length
                    writer.Write(digestValue);               // Value
                }
                return(stream.ToArray());
            }
        }
Example #3
0
        private static byte[] EncodeDigestValue(SignaturePayload signaturePayload)
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    WriteOid(writer, signaturePayload.DigestAlgorithm);

                    writer.Write((byte)0x04); // Tag = OCTET STRING
                    WriteLength(writer, signaturePayload.Digest.Length);
                    writer.Write(signaturePayload.Digest);
                }

                return stream.ToArray();
            }
        }
Example #4
0
        private static byte[] EncodeDigestValue(SignaturePayload signaturePayload)
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    WriteOid(writer, signaturePayload.DigestAlgorithm);

                    writer.Write((byte)0x04); // Tag = OCTET STRING
                    WriteLength(writer, signaturePayload.Digest.Length);
                    writer.Write(signaturePayload.Digest);
                }

                return(stream.ToArray());
            }
        }
Example #5
0
        // ASN.1 Structure
        // SignaturePayload ::= SEQUENCE {
        //     version             INTEGER { v1(1) },
        //     contentIdentifier   UTF8String,
        //     contentDigest       DigestValue }
        // DigestValue ::= SEQUENCE  {
        //     digestAlgorithm     OBJECT IDENTIFIER
        //     digest              OCTET STRING }
        internal static byte[] EncodePayload(SignaturePayload signaturePayload)
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    // Generate the sub-elements
                    byte[] contents = EncodePayloadContents(signaturePayload);

                    // Write the tag and length
                    writer.Write((byte)0x30); // Tag = SEQUENCE (constructed)
                    WriteLength(writer, contents.Length); // Length
                    writer.Write(contents); // Value
                }
                return stream.ToArray();
            }
        }
Example #6
0
        // ASN.1 Structure
        // SignaturePayload ::= SEQUENCE {
        //     version             INTEGER { v1(1) },
        //     contentIdentifier   UTF8String,
        //     contentDigest       DigestValue }
        // DigestValue ::= SEQUENCE  {
        //     digestAlgorithm     OBJECT IDENTIFIER
        //     digest              OCTET STRING }

        internal static byte[] EncodePayload(SignaturePayload signaturePayload)
        {
            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    // Generate the sub-elements
                    byte[] contents = EncodePayloadContents(signaturePayload);

                    // Write the tag and length
                    writer.Write((byte)0x30);             // Tag = SEQUENCE (constructed)
                    WriteLength(writer, contents.Length); // Length
                    writer.Write(contents);               // Value
                }
                return(stream.ToArray());
            }
        }
Example #7
0
        private void SetSignature(SignedCms cms)
        {
            TrustedSigningTimeUtc = null;
            Payload    = SignaturePayload.Decode(cms.ContentInfo.Content);
            _signature = cms;

            // Load the encrypted digest using the native APIs
            using (var nativeCms = NativeCms.Decode(cms.Encode(), detached: false))
            {
                _encryptedDigest = nativeCms.GetEncryptedDigest();
            }

            var signerInfo = _signature.SignerInfos.Cast <SignerInfo>().FirstOrDefault();

            if (signerInfo != null)
            {
                Signer = Signer.FromSignerInfo(signerInfo);

                // Check for a timestamper
                var attr = signerInfo
                           .UnsignedAttributes
                           .Cast <CryptographicAttributeObject>()
                           .FirstOrDefault(c => c.Oid.Value.Equals(Constants.SignatureTimeStampTokenAttributeOid.Value, StringComparison.OrdinalIgnoreCase));
                if (attr != null && attr.Values.Count > 0)
                {
                    var timestamp = new SignedCms();
                    timestamp.Decode(attr.Values[0].RawData);

                    // Check the timestamp against the data
                    var token = RFC3161.VerifyTimestamp(_encryptedDigest, timestamp);
                    _timestamp = token;

                    if (_timestamp.IsTrusted)
                    {
                        TrustedSigningTimeUtc = _timestamp.TimestampUtc;
                    }
                }
            }
        }
Example #8
0
        public static async Task <int> CreateSigningRequest(string fileName, string outputFile, string digestAlgorithm)
        {
            // Set default values
            outputFile      = outputFile ?? (fileName + ".req");
            digestAlgorithm = digestAlgorithm ?? Signature.DefaultDigestAlgorithmName;

            if (File.Exists(outputFile))
            {
                AnsiConsole.Error.WriteLine("Signature request already exists: " + outputFile);
                return(1);
            }

            // Create the signature
            AnsiConsole.Output.WriteLine("Computing Signature Request...");
            var sig = new Signature(SignaturePayload.Compute(fileName, digestAlgorithm));

            AnsiConsole.Output.WriteLine("Signature request written to " + outputFile);

            // Write the unsigned request
            await sig.WriteAsync(outputFile);

            return(0);
        }
Example #9
0
 /// <summary>
 /// Constructs a new signature request for the specified file
 /// </summary>
 /// <param name="payload">A signature entry describing the file to create a signature request for</param>
 /// <remarks>
 /// Until <see cref="Sign"/> is called, this structure represents a signature request.
 /// </remarks>
 public Signature(SignaturePayload payload)
 {
     Payload = payload;
 }
Example #10
0
        public static async Task <int> Sign(string fileName, IEnumerable <CommandOption> options)
        {
            var signOptions = SignOptions.FromOptions(fileName, options);

            X509Certificate2Collection includedCerts;
            var signingCert = signOptions.FindCert(out includedCerts);

            if (signingCert == null)
            {
                AnsiConsole.Error.WriteLine("Unable to find certificate that meets the specified criteria");
                return(1);
            }
            AnsiConsole.Output.WriteLine("Signing file with: " + signingCert.SubjectName.CommonName());

            // Load the private key if provided
            if (!string.IsNullOrEmpty(signOptions.CspName) && !string.IsNullOrEmpty(signOptions.KeyContainer))
            {
                var parameters = new CspParameters()
                {
                    ProviderType     = 1, // PROV_RSA_FULL
                    KeyNumber        = (int)KeyNumber.Signature,
                    ProviderName     = signOptions.CspName,
                    KeyContainerName = signOptions.KeyContainer
                };
                signingCert.PrivateKey = new RSACryptoServiceProvider(parameters);
            }

            if (!signingCert.HasPrivateKey)
            {
                AnsiConsole.Error.WriteLine("Unable to find private key for certificate: " + signingCert.SubjectName.CommonName());
                return(1);
            }

            // If the input file didn't provide any additional certs, set up a new collection
            var additionalCerts = new X509Certificate2Collection();

            // Load any additional certs requested by the user
            if (!string.IsNullOrEmpty(signOptions.AddCertificatesFile))
            {
                additionalCerts.Import(signOptions.AddCertificatesFile);
            }

            // Determine if we are signing a request or a file
            Signature sig = await Signature.TryDecodeAsync(fileName);

            if (sig == null)
            {
                sig = new Signature(SignaturePayload.Compute(fileName, Signature.DefaultDigestAlgorithmName));
            }

            // Verify that the content is unsigned
            if (sig.IsSigned)
            {
                AnsiConsole.Error.WriteLine("File already signed: " + fileName);
                return(1);
            }

            // Sign the file
            sig.Sign(signingCert, includedCerts, additionalCerts);

            AnsiConsole.Output.WriteLine("Successfully signed.");

            if (!string.IsNullOrEmpty(signOptions.Timestamper))
            {
                // Timestamp the signature
                AnsiConsole.Output.WriteLine("Transmitting signature to timestamping authority...");
                sig.Timestamp(new Uri(signOptions.Timestamper), signOptions.TimestamperAlgorithm ?? Signature.DefaultDigestAlgorithmName);
                AnsiConsole.Output.WriteLine("Trusted timestamp applied to signature.");
            }

            // Write the signature
            AnsiConsole.Output.WriteLine("Signature saved to " + signOptions.Output);
            await sig.WriteAsync(signOptions.Output);

            return(0);
        }
Example #11
0
 /// <summary>
 /// Constructs a new signature request for the specified file
 /// </summary>
 /// <param name="payload">A signature entry describing the file to create a signature request for</param>
 /// <remarks>
 /// Until <see cref="Sign"/> is called, this structure represents a signature request.
 /// </remarks>
 public Signature(SignaturePayload payload)
 {
     Payload = payload;
 }
Example #12
0
        private static Signature DecodeRequest(byte[] data)
        {
            var payload = SignaturePayload.Decode(data);

            return(new Signature(payload));
        }