예제 #1
0
 protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <string, ushort> domainNames)
 {
     messageData[currentPosition++] = (byte)HashAlgorithm;
     messageData[currentPosition++] = Flags;
     DnsMessageBase.EncodeUShort(messageData, ref currentPosition, Iterations);
     messageData[currentPosition++] = (byte)Salt.Length;
     DnsMessageBase.EncodeByteArray(messageData, ref currentPosition, Salt);
     messageData[currentPosition++] = (byte)NextHashedOwnerName.Length;
     DnsMessageBase.EncodeByteArray(messageData, ref currentPosition, NextHashedOwnerName);
     NSecRecord.EncodeTypeBitmap(messageData, ref currentPosition, Types);
 }
예제 #2
0
        private async Task <DnsSecValidationResult> ValidateNSecAsync(DomainName name, RecordType recordType, RecordClass recordClass, List <RrSigRecord> rrSigRecords, DomainName stop, DomainName zoneApex, DnsMessageBase msg, TState state, CancellationToken token)
        {
            List <NSecRecord> nsecRecords = msg.AuthorityRecords.OfType <NSecRecord>().ToList();

            if (nsecRecords.Count == 0)
            {
                return(DnsSecValidationResult.Indeterminate);
            }

            foreach (var nsecGroup in nsecRecords.GroupBy(x => x.Name))
            {
                DnsSecValidationResult validationResult = await ValidateRrSigAsync(nsecGroup.Key, RecordType.NSec, recordClass, nsecGroup.ToList(), rrSigRecords, zoneApex, msg, state, token);

                if (validationResult != DnsSecValidationResult.Signed)
                {
                    return(validationResult);
                }
            }

            DomainName current = name;

            while (true)
            {
                if (current.Equals(stop))
                {
                    return(DnsSecValidationResult.Signed);
                }

                NSecRecord nsecRecord = nsecRecords.FirstOrDefault(x => x.Name.Equals(current));
                if (nsecRecord != null)
                {
                    return(nsecRecord.Types.Contains(recordType) ? DnsSecValidationResult.Bogus : DnsSecValidationResult.Signed);
                }
                else
                {
                    nsecRecord = nsecRecords.FirstOrDefault(x => x.IsCovering(current, zoneApex));
                    if (nsecRecord == null)
                    {
                        return(DnsSecValidationResult.Bogus);
                    }
                }

                // Updated the following lines to fix an issue where an NSEC entry is present for a parent domain but is not a wildcard entry.
                if (current.Labels[0] == "*")
                {
                    current = current.GetParentName();
                }
                else
                {
                    current = DomainName.Asterisk + current.GetParentName();
                }
            }
        }
예제 #3
0
        internal override void ParseRecordData(byte[] resultData, int currentPosition, int length)
        {
            int endPosition = currentPosition + length;

            HashAlgorithm = (NSec3HashAlgorithm)resultData[currentPosition++];
            Flags         = resultData[currentPosition++];
            Iterations    = DnsMessageBase.ParseUShort(resultData, ref currentPosition);
            int saltLength = resultData[currentPosition++];

            Salt = DnsMessageBase.ParseByteData(resultData, ref currentPosition, saltLength);
            int hashLength = resultData[currentPosition++];

            NextHashedOwnerName = DnsMessageBase.ParseByteData(resultData, ref currentPosition, hashLength);
            Types = NSecRecord.ParseTypeBitMap(resultData, ref currentPosition, endPosition);
        }
예제 #4
0
        private Zone SignWithNSec(DateTime inception, DateTime expiration, List <DnsKeyRecord> zoneSigningKeys, List <DnsKeyRecord> keySigningKeys)
        {
            var soaRecord     = _records.OfType <SoaRecord>().First();
            var subZones      = _records.Where(x => (x.RecordType == RecordType.Ns) && (x.Name != Name)).Select(x => x.Name).Distinct().ToList();
            var glueRecords   = _records.Where(x => subZones.Any(y => x.Name.IsSubDomainOf(y))).ToList();
            var recordsByName = _records.Except(glueRecords).Union(zoneSigningKeys).Union(keySigningKeys).GroupBy(x => x.Name).Select(x => new Tuple <DomainName, List <DnsRecordBase> >(x.Key, x.OrderBy(y => y.RecordType == RecordType.Soa ? -1 : (int)y.RecordType).ToList())).OrderBy(x => x.Item1).ToList();

            Zone res = new Zone(Name, Count * 3);

            for (int i = 0; i < recordsByName.Count; i++)
            {
                List <RecordType> recordTypes = new List <RecordType>();

                DomainName currentName = recordsByName[i].Item1;

                foreach (var recordsByType in recordsByName[i].Item2.GroupBy(x => x.RecordType))
                {
                    List <DnsRecordBase> records = recordsByType.ToList();

                    recordTypes.Add(recordsByType.Key);
                    res.AddRange(records);

                    // do not sign nameserver delegations for sub zones
                    if ((records[0].RecordType == RecordType.Ns) && (currentName != Name))
                    {
                        continue;
                    }

                    recordTypes.Add(RecordType.RrSig);

                    foreach (var key in zoneSigningKeys)
                    {
                        res.Add(new RrSigRecord(records, key, inception, expiration));
                    }
                    if (records[0].RecordType == RecordType.DnsKey)
                    {
                        foreach (var key in keySigningKeys)
                        {
                            res.Add(new RrSigRecord(records, key, inception, expiration));
                        }
                    }
                }

                recordTypes.Add(RecordType.NSec);

                NSecRecord nsecRecord = new NSecRecord(recordsByName[i].Item1, soaRecord.RecordClass, soaRecord.NegativeCachingTTL, recordsByName[(i + 1) % recordsByName.Count].Item1, recordTypes);
                res.Add(nsecRecord);

                foreach (var key in zoneSigningKeys)
                {
                    res.Add(new RrSigRecord(new List <DnsRecordBase>()
                    {
                        nsecRecord
                    }, key, inception, expiration));
                }
            }

            res.AddRange(glueRecords);

            return(res);
        }