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); }
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(); } } }
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); }
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); }