internal static Accuracy Read(DerSequenceReader reader)
        {
            var accuracyReader = reader.ReadSequence();
            int?seconds        = null;
            int?milliseconds   = null;
            int?microseconds   = null;

            if (accuracyReader.HasTag(DerSequenceReader.DerTag.Integer))
            {
                seconds = accuracyReader.ReadInteger();

                if (seconds < 0)
                {
                    // The ASN.1 definition does not disallow negative numbers
                    // but it doesn't make sense to allow negative numbers.
                    throw new CryptographicException(Strings.InvalidAsn1);
                }
            }

            if (accuracyReader.HasTag(DerSequenceReader.ContextSpecificTagFlag))
            {
                milliseconds = accuracyReader.ReadInteger();

                if (milliseconds < 1 || milliseconds > 999)
                {
                    throw new CryptographicException(Strings.InvalidAsn1);
                }
            }

            if (accuracyReader.HasTag(DerSequenceReader.ContextSpecificTagFlag | 1))
            {
                microseconds = accuracyReader.ReadInteger();

                if (microseconds < 1 || microseconds > 999)
                {
                    throw new CryptographicException(Strings.InvalidAsn1);
                }
            }

            if (accuracyReader.HasData)
            {
                throw new CryptographicException(Strings.InvalidAsn1);
            }

            return(new Accuracy(seconds, milliseconds, microseconds));
        }
Example #2
0
        internal static MessageImprint Read(DerSequenceReader reader)
        {
            var imprintReader = reader.ReadSequence();
            var hashAlgorithm = AlgorithmIdentifier.Read(imprintReader);
            var hashedMessage = imprintReader.ReadOctetString();

            if (hashedMessage == null || hashedMessage.Length == 0)
            {
                throw new CryptographicException(Strings.InvalidAsn1);
            }

            if (imprintReader.HasData)
            {
                throw new CryptographicException(Strings.InvalidAsn1);
            }

            return(new MessageImprint(hashAlgorithm, hashedMessage));
        }
        internal static EssCertId Read(DerSequenceReader reader)
        {
            var          sequenceReader = reader.ReadSequence();
            var          hash           = sequenceReader.ReadOctetString();
            IssuerSerial issuerSerial   = null;

            if (sequenceReader.HasData)
            {
                issuerSerial = IssuerSerial.Read(sequenceReader);

                if (sequenceReader.HasData)
                {
                    throw new SignatureException(Strings.SigningCertificateInvalid);
                }
            }

            return(new EssCertId(hash, issuerSerial));
        }
Example #4
0
        private static IReadOnlyList <GeneralName> ReadGeneralNames(DerSequenceReader reader)
        {
            var sequenceReader = reader.ReadSequence();
            var generalNames   = new List <GeneralName>(capacity: 1);

            var generalName = GeneralName.Read(sequenceReader);

            if (generalName != null)
            {
                generalNames.Add(generalName);
            }

            if (sequenceReader.HasData)
            {
                throw new SignatureException(Strings.InvalidAsn1);
            }

            return(generalNames.AsReadOnly());
        }
        internal static CommitmentTypeQualifier Read(DerSequenceReader reader)
        {
            var commitmentTypeQualifierReader = reader.ReadSequence();
            var commitmentTypeIdentifier      = commitmentTypeQualifierReader.ReadOid();

            byte[] qualifier = null;

            if (commitmentTypeQualifierReader.HasData)
            {
                qualifier = commitmentTypeQualifierReader.ReadNextEncodedValue();

                if (commitmentTypeQualifierReader.HasData)
                {
                    throw new SignatureException(Strings.InvalidAsn1);
                }
            }

            return(new CommitmentTypeQualifier(commitmentTypeIdentifier, qualifier));
        }
Example #6
0
        internal static AlgorithmIdentifier Read(DerSequenceReader reader)
        {
            var algIdReader = reader.ReadSequence();
            var algorithm   = algIdReader.ReadOid();

            // For all algorithms we currently support, parameter must be null.
            // However, presence of a DER encoded NULL value is optional.
            if (algIdReader.HasData)
            {
                algIdReader.ReadNull();

                if (algIdReader.HasData)
                {
                    throw new SignatureException(Strings.SigningCertificateV2Invalid);
                }
            }

            return(new AlgorithmIdentifier(algorithm));
        }
Example #7
0
        internal static PolicyQualifierInfo Read(DerSequenceReader reader)
        {
            var policyQualifierReader = reader.ReadSequence();
            var policyQualifierId     = policyQualifierReader.ReadOid();

            byte[] qualifier = null;

            if (policyQualifierReader.HasData)
            {
                qualifier = policyQualifierReader.ReadNextEncodedValue();

                if (policyQualifierReader.HasData)
                {
                    throw new SignatureException(Strings.InvalidAsn1);
                }
            }

            return(new PolicyQualifierInfo(policyQualifierId, qualifier));
        }
Example #8
0
        internal static Extensions Read(DerSequenceReader reader)
        {
            var extensionsReader = reader.ReadSequence();
            var extensions       = new List <Extension>();

            while (extensionsReader.HasData)
            {
                var extension = Extension.Read(extensionsReader);

                extensions.Add(extension);
            }

            if (extensions.Count == 0)
            {
                throw new CryptographicException(Strings.InvalidAsn1);
            }

            return(new Extensions(extensions));
        }
Example #9
0
        internal static Extension Read(DerSequenceReader reader)
        {
            var extensionReader = reader.ReadSequence();
            var oid             = extensionReader.ReadOid();
            var critical        = false;

            if (extensionReader.HasTag(DerSequenceReader.DerTag.Boolean))
            {
                critical = extensionReader.ReadBoolean();
            }

            var value = extensionReader.ReadOctetString();

            if (extensionReader.HasData)
            {
                throw new CryptographicException(Strings.InvalidAsn1);
            }

            return(new Extension(oid, critical, value));
        }
Example #10
0
        public static void InteriorLengthTooLong_Nested()
        {
            byte[] bytes =
            {
                // CONSTRUCTED SEQUENCE (9 bytes)
                0x30, 0x09,

                // CONSTRUCTED SEQUENCE (2 bytes)
                0x30, 0x02,

                // OCTET STRING (1 byte, but 0 remain for the inner sequence)
                0x04, 0x01,

                // OCTET STRING (in the outer sequence, after the inner sequence, 3 bytes)
                0x04, 0x03, 0x01, 0x02, 0x03
            };

            DerSequenceReader reader = new DerSequenceReader(bytes);
            DerSequenceReader nested = reader.ReadSequence();

            Assert.Throws <CryptographicException>(() => nested.ReadOctetString());
        }
Example #11
0
        public static void InteriorLengthTooLong()
        {
            byte[] bytes =
            {
                // CONSTRUCTED SEQUENCE (8 bytes)
                0x30, 0x08,

                // CONSTRUCTED SEQUENCE (2 bytes)
                0x30, 0x02,

                // OCTET STRING (0 bytes)
                0x04, 0x00,

                // OCTET STRING (after the inner sequence, 3 bytes, but that exceeds the sequence bounds)
                0x04, 0x03, 0x01, 0x02, 0x03
            };

            DerSequenceReader reader = new DerSequenceReader(bytes);
            DerSequenceReader nested = reader.ReadSequence();

            Assert.Equal(0, nested.ReadOctetString().Length);
            Assert.False(nested.HasData);
            Assert.Throws <CryptographicException>(() => reader.ReadOctetString());
        }
        internal static NuGetPackageOwners Read(DerSequenceReader reader)
        {
            var packageOwners = new List <string>();
            var ownersReader  = reader.ReadSequence();

            while (ownersReader.HasData)
            {
                var packageOwner = ownersReader.ReadUtf8String();

                if (string.IsNullOrWhiteSpace(packageOwner))
                {
                    throw new SignatureException(Strings.NuGetPackageOwnersInvalid);
                }

                packageOwners.Add(packageOwner);
            }

            if (packageOwners.Count == 0)
            {
                throw new SignatureException(Strings.NuGetPackageOwnersInvalid);
            }

            return(new NuGetPackageOwners(packageOwners));
        }
        internal static string FindHttpAiaRecord(byte[] authorityInformationAccess, string recordTypeOid)
        {
            DerSequenceReader reader = new DerSequenceReader(authorityInformationAccess);

            while (reader.HasData)
            {
                DerSequenceReader innerReader = reader.ReadSequence();

                // If the sequence's first element is a sequence, unwrap it.
                if (innerReader.PeekTag() == ConstructedSequenceTagId)
                {
                    innerReader = innerReader.ReadSequence();
                }

                Oid oid = innerReader.ReadOid();

                if (StringComparer.Ordinal.Equals(oid.Value, recordTypeOid))
                {
                    string uri = innerReader.ReadIA5String();

                    Uri parsedUri;
                    if (!Uri.TryCreate(uri, UriKind.Absolute, out parsedUri))
                    {
                        continue;
                    }

                    if (!StringComparer.Ordinal.Equals(parsedUri.Scheme, "http"))
                    {
                        continue;
                    }

                    return uri;
                }
            }

            return null;
        }
Example #14
0
        private static string GetCdpUrl(X509Certificate2 cert)
        {
            byte[] crlDistributionPoints = null;

            foreach (X509Extension extension in cert.Extensions)
            {
                if (StringComparer.Ordinal.Equals(extension.Oid.Value, Oids.CrlDistributionPoints))
                {
                    // If there's an Authority Information Access extension, it might be used for
                    // looking up additional certificates for the chain.
                    crlDistributionPoints = extension.RawData;
                    break;
                }
            }

            if (crlDistributionPoints == null)
            {
                return null;
            }

            // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
            //
            // DistributionPoint ::= SEQUENCE {
            //    distributionPoint       [0]     DistributionPointName OPTIONAL,
            //    reasons                 [1]     ReasonFlags OPTIONAL,
            //    cRLIssuer               [2]     GeneralNames OPTIONAL }
            //
            // DistributionPointName ::= CHOICE {
            //    fullName                [0]     GeneralNames,
            //    nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
            //
            // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
            //
            // GeneralName ::= CHOICE {
            //    otherName                       [0]     OtherName,
            //    rfc822Name                      [1]     IA5String,
            //    dNSName                         [2]     IA5String,
            //    x400Address                     [3]     ORAddress,
            //    directoryName                   [4]     Name,
            //    ediPartyName                    [5]     EDIPartyName,
            //    uniformResourceIdentifier       [6]     IA5String,
            //    iPAddress                       [7]     OCTET STRING,
            //    registeredID                    [8]     OBJECT IDENTIFIER }

            DerSequenceReader cdpSequence = new DerSequenceReader(crlDistributionPoints);

            while (cdpSequence.HasData)
            {
                const byte ContextSpecificFlag = 0x80;
                const byte ContextSpecific0 = ContextSpecificFlag;
                const byte ConstructedFlag = 0x20;
                const byte ContextSpecificConstructed0 = ContextSpecific0 | ConstructedFlag;
                const byte GeneralNameUri = ContextSpecificFlag | 0x06;

                DerSequenceReader distributionPointReader = cdpSequence.ReadSequence();
                byte tag = distributionPointReader.PeekTag();

                // Only distributionPoint is supported
                if (tag != ContextSpecificConstructed0)
                {
                    continue;
                }

                // The DistributionPointName is a CHOICE, not a SEQUENCE, but the reader is the same.
                DerSequenceReader dpNameReader = distributionPointReader.ReadSequence();
                tag = dpNameReader.PeekTag();

                // Only fullName is supported,
                // nameRelativeToCRLIssuer is for LDAP-based lookup.
                if (tag != ContextSpecificConstructed0)
                {
                    continue;
                }

                DerSequenceReader fullNameReader = dpNameReader.ReadSequence();

                while (fullNameReader.HasData)
                {
                    tag = fullNameReader.PeekTag();

                    if (tag != GeneralNameUri)
                    {
                        fullNameReader.SkipValue();
                        continue;
                    }

                    string uri = fullNameReader.ReadIA5String();

                    Uri parsedUri = new Uri(uri);

                    if (!StringComparer.Ordinal.Equals(parsedUri.Scheme, "http"))
                    {
                        continue;
                    }

                    return uri;
                }
            }

            return null;
        }
Example #15
0
        internal static TstInfo Read(DerSequenceReader reader)
        {
            var tstInfoReader  = reader.ReadSequence();
            var version        = tstInfoReader.ReadInteger();
            var policy         = tstInfoReader.ReadOid();
            var messageImprint = MessageImprint.Read(tstInfoReader);
            var serialNumber   = tstInfoReader.ReadIntegerBytes();

            if (serialNumber == null || serialNumber.Length == 0)
            {
                throw new CryptographicException(Strings.InvalidAsn1);
            }

            var genTime = tstInfoReader.ReadGeneralizedTime();

            Accuracy accuracy = null;

            if (tstInfoReader.HasTag(DerSequenceReader.ConstructedSequence))
            {
                accuracy = Accuracy.Read(tstInfoReader);
            }

            var ordering = false;

            if (tstInfoReader.HasTag(DerSequenceReader.DerTag.Boolean))
            {
                ordering = tstInfoReader.ReadBoolean();
            }

            byte[] nonce = null;

            if (tstInfoReader.HasTag(DerSequenceReader.DerTag.Integer))
            {
                nonce = tstInfoReader.ReadIntegerBytes();
            }

            byte[] tsa = null;

            if (tstInfoReader.HasData && tstInfoReader.HasTag(DerSequenceReader.ContextSpecificConstructedTag0))
            {
                tsa = tstInfoReader.ReadValue((DerSequenceReader.DerTag)DerSequenceReader.ContextSpecificConstructedTag0);
            }

            X509ExtensionCollection extensions = null;

            if (tstInfoReader.HasData && tstInfoReader.HasTag(DerSequenceReader.ContextSpecificConstructedTag1))
            {
                extensions = new X509ExtensionCollection();

                var rawExtensions = Signing.Extensions.Read(tstInfoReader);

                foreach (var rawExtension in rawExtensions.ExtensionsList)
                {
                    extensions.Add(
                        new X509Extension(
                            rawExtension.Id,
                            rawExtension.Value,
                            rawExtension.Critical));
                }

                if (extensions.Count == 0)
                {
                    throw new CryptographicException(Strings.InvalidAsn1);
                }
            }

            if (tstInfoReader.HasData)
            {
                throw new CryptographicException(Strings.InvalidAsn1);
            }

            return(new TstInfo(
                       version,
                       policy,
                       messageImprint,
                       serialNumber,
                       genTime.ToUniversalTime(),
                       accuracy,
                       ordering,
                       nonce,
                       tsa,
                       extensions));
        }
        private static DerSequenceReader ReadEncryptedPkcs8Blob(string passphrase, DerSequenceReader reader)
        {
            // EncryptedPrivateKeyInfo::= SEQUENCE {
            //    encryptionAlgorithm EncryptionAlgorithmIdentifier,
            //    encryptedData        EncryptedData }
            //
            // EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
            //
            // EncryptedData ::= OCTET STRING
            DerSequenceReader algorithmIdentifier = reader.ReadSequence();
            string            algorithmOid        = algorithmIdentifier.ReadOidAsString();

            // PBES2 (Password-Based Encryption Scheme 2)
            if (algorithmOid != OidPbes2)
            {
                Debug.Fail($"Expected PBES2 ({OidPbes2}), got {algorithmOid}");
                throw new CryptographicException();
            }

            // PBES2-params ::= SEQUENCE {
            //    keyDerivationFunc AlgorithmIdentifier { { PBES2 - KDFs} },
            //    encryptionScheme AlgorithmIdentifier { { PBES2 - Encs} }
            // }

            DerSequenceReader pbes2Params = algorithmIdentifier.ReadSequence();

            algorithmIdentifier = pbes2Params.ReadSequence();

            string kdfOid = algorithmIdentifier.ReadOidAsString();

            // PBKDF2 (Password-Based Key Derivation Function 2)
            if (kdfOid != OidPbkdf2)
            {
                Debug.Fail($"Expected PBKDF2 ({OidPbkdf2}), got {kdfOid}");
                throw new CryptographicException();
            }

            // PBKDF2-params ::= SEQUENCE {
            //   salt CHOICE {
            //     specified OCTET STRING,
            //     otherSource AlgorithmIdentifier { { PBKDF2 - SaltSources} }
            //   },
            //   iterationCount INTEGER (1..MAX),
            //   keyLength INTEGER(1..MAX) OPTIONAL,
            //   prf AlgorithmIdentifier { { PBKDF2 - PRFs} }  DEFAULT algid - hmacWithSHA1
            // }
            DerSequenceReader pbkdf2Params = algorithmIdentifier.ReadSequence();

            byte[] salt      = pbkdf2Params.ReadOctetString();
            int    iterCount = pbkdf2Params.ReadInteger();
            int    keySize   = -1;

            if (pbkdf2Params.HasData && pbkdf2Params.PeekTag() == (byte)DerSequenceReader.DerTag.Integer)
            {
                keySize = pbkdf2Params.ReadInteger();
            }

            if (pbkdf2Params.HasData)
            {
                string prfOid = pbkdf2Params.ReadOidAsString();

                // SHA-1 is the only hash algorithm our PBKDF2 supports.
                if (prfOid != OidSha1)
                {
                    Debug.Fail($"Expected SHA1 ({OidSha1}), got {prfOid}");
                    throw new CryptographicException();
                }
            }

            DerSequenceReader encryptionScheme = pbes2Params.ReadSequence();
            string            cipherOid        = encryptionScheme.ReadOidAsString();

            // DES-EDE3-CBC (TripleDES in CBC mode)
            if (cipherOid != OidTripleDesCbc)
            {
                Debug.Fail($"Expected DES-EDE3-CBC ({OidTripleDesCbc}), got {cipherOid}");
                throw new CryptographicException();
            }

            byte[] decrypted;

            using (TripleDES des3 = TripleDES.Create())
            {
                if (keySize == -1)
                {
                    foreach (KeySizes keySizes in des3.LegalKeySizes)
                    {
                        keySize = Math.Max(keySize, keySizes.MaxSize);
                    }
                }

                byte[] iv = encryptionScheme.ReadOctetString();

                using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(passphrase, salt, iterCount))
                    using (ICryptoTransform decryptor = des3.CreateDecryptor(pbkdf2.GetBytes(keySize / 8), iv))
                    {
                        byte[] encrypted = reader.ReadOctetString();
                        decrypted = decryptor.TransformFinalBlock(encrypted, 0, encrypted.Length);
                    }
            }

            DerSequenceReader pkcs8Reader = new DerSequenceReader(decrypted);

            return(pkcs8Reader);
        }
        private static X509Certificate2 DownloadCertificate(
            byte[] authorityInformationAccess,
            ref TimeSpan remainingDownloadTime)
        {
            // Don't do any work if we're over limit.
            if (remainingDownloadTime <= TimeSpan.Zero)
            {
                return null;
            }

            DerSequenceReader reader = new DerSequenceReader(authorityInformationAccess);

            while (reader.HasData)
            {
                DerSequenceReader innerReader = reader.ReadSequence();

                // If the sequence's first element is a sequence, unwrap it.
                if (innerReader.PeekTag() == ConstructedSequenceTagId)
                {
                    innerReader = innerReader.ReadSequence();
                }

                Oid oid = innerReader.ReadOid();

                if (StringComparer.Ordinal.Equals(oid.Value, Oids.CertificateAuthorityIssuers))
                {
                    string uri = innerReader.ReadIA5String();

                    Uri parsedUri;
                    if (!Uri.TryCreate(uri, UriKind.Absolute, out parsedUri))
                    {
                        continue;
                    }

                    if (!StringComparer.Ordinal.Equals(parsedUri.Scheme, "http"))
                    {
                        continue;
                    }

                    return CertificateAssetDownloader.DownloadCertificate(uri, ref remainingDownloadTime);
                }
            }

            return null;
        }
Example #18
0
        internal static ISet<string> ReadCertPolicyExtension(X509Extension extension)
        {
            DerSequenceReader reader = new DerSequenceReader(extension.RawData);
            HashSet<string> policies = new HashSet<string>();

            while (reader.HasData)
            {
                DerSequenceReader policyInformation = reader.ReadSequence();
                policies.Add(policyInformation.ReadOidAsString());

                // There is an optional policy qualifier here, but it is for information
                // purposes, there is no logic that would be changed.

                // Since reader (the outer one) has already skipped past the rest of the
                // sequence we don't particularly need to drain out here.
            }

            return policies;
        }
Example #19
0
        private static List<CertificatePolicyMapping> ReadCertPolicyMappingsExtension(X509Extension extension)
        {
            DerSequenceReader reader = new DerSequenceReader(extension.RawData);
            List<CertificatePolicyMapping> mappings = new List<CertificatePolicyMapping>();

            while (reader.HasData)
            {
                DerSequenceReader mappingSequence = reader.ReadSequence();
                mappings.Add(
                    new CertificatePolicyMapping
                    {
                        IssuerDomainPolicy = mappingSequence.ReadOidAsString(),
                        SubjectDomainPolicy = mappingSequence.ReadOidAsString(),
                    });
            }

            return mappings;
        }