private static byte[] GetCanonicalRRData(DnsKeyRecord rec)
 {
     using (var ms = new MemoryStream())
     {
         ms.Write(BitConverter.GetBytes(rec.Flags).Reverse(), 0, 2);
         ms.Write(new[] { rec.Protocol }, 0, 1);
         ms.Write(new[] { (byte)rec.Algorithm }, 0, 1);
         ms.Write(rec.PublicKey, 0, rec.PublicKey.Length);
         return(ms.ToArray());
     }
 }
        public static byte[] GetCanonicalFormatData(int ttl, DnsKeyRecord rec)
        {
            var rrdata = GetCanonicalRRData(rec);

            using (var ms = new MemoryStream())
            {
                byte[] domainBytes = CanonicalFormatHelper.BuildUnpackedDomainInCanonicalForm(rec.Name);
                ms.Write(domainBytes, 0, domainBytes.Length);
                ms.Write(BitConverter.GetBytes((ushort)rec.RecordType).Reverse(), 0, 2);
                ms.Write(BitConverter.GetBytes((ushort)rec.RecordClass).Reverse(), 0, 2);
                ms.Write(BitConverter.GetBytes(ttl).Reverse(), 0, 4);
                ms.Write(BitConverter.GetBytes((ushort)rrdata.Length).Reverse(), 0, 2);
                ms.Write(rrdata, 0, rrdata.Length);
                return(ms.ToArray());
            }
        }
Пример #3
0
        static void Main(string[] args)
        {
            // PrintAlgorithms();
            // EqualityCheck();
            // TestKeyPair();

            // https://www.cloudflare.com/dns/dnssec/how-dnssec-works/
            // RRSIG - Contains a cryptographic signature
            // DNSKEY - Contains a public signing key
            // DS - Contains the hash of a DNSKEY record
            // NSEC and NSEC3 - For explicit denial-of-existence of a DNS record
            // CDNSKEY and CDS - For a child zone requesting updates to DS record(s) in the parent zone.


            // The first step towards securing a zone with DNSSEC
            // is to group all the records (on the same label?) with the same type into a resource record set(RRset).
            // It’s actually this full RRset that gets digitally signed, opposed to individual DNS records.
            // Of course, this also means that you must request and validate all of the AAAA records
            // from a zone with the same label instead of validating only one of them.


            // zone-signing key (ZSK)pair:
            // the private portion of the key digitally signs each RRset in the zone,
            // while the public portion verifies the signature.
            // a zone operator creates digital signatures for each RRset using the private ZSK
            // and stores them in their name server as RRSIG records.

            // The zone operator also needs to make their public ZSK available by adding it to their name server in a DNSKEY record.

            // the name server also returns the corresponding RRSIG.
            // The resolver can then pull the DNSKEY record containing the public ZSK from the name server.
            // Together, the RRset, RRSIG, and public ZSK can validate the response.

            // If we trust the zone - signing key in the DNSKEY record, we can trust all the records in the zone.
            // But, what if the zone - signing key was compromised? We need a way to validate the public ZSK.

            // Key-Signing Keys (KSK):
            // The KSK validates the DNSKEY record in exactly the same way as our ZSK secured the rest of our RRsets.
            // It signs the public ZSK (which is stored in a DNSKEY record), creating an RRSIG for the DNSKEY.

            // Just like the public ZSK, the name server publishes the public KSK in another DNSKEY record,
            // which gives us the DNSKEY RRset shown above.
            // Both the public KSK and public ZSK are signed by the private KSK.
            // Resolvers can then use the public KSK to validate the public ZSK.

            // Complicating things further, the key-signing key is signed by itself, which doesn’t provide any additional trust.
            // We need a way to connect the trust in our zone with its parent zone.


            // Delegation Signer Records
            // DNSSEC introduces a delegation signer(DS) record to allow the transfer of trust
            // from a parent zone to a child zone. A zone operator hashes the DNSKEY record
            // containing the public KSK and gives it to the parent zone to publish as a DS record.

            // This DS record is how resolvers know that the child zone is DNSSEC - enabled.
            // To check the validity of the child zone’s public KSK,
            // the resolver hashes it and compares it to the DS record from the parent.
            // If they match, the resolver can assume that the public KSK hasn’t been tampered with,
            // which means it can trust all of the records in the child zone.
            // This is how a chain of trust is established in DNSSEC.


            // System.Security.Cryptography.X509Certificates.X509Certificate2 cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(byte[] rawData);
            // System.Security.Cryptography.X509Certificates.X509Certificate2 cert2 = DotNetUtilities.CreateX509Cert2("mycert");
            // SecurityKey secKey = new X509SecurityKey(cert2);

            // https://tools.ietf.org/html/rfc4034
            // https://www.dynu.com/Resources/DNS-Records/DNSKEY-Record


            AaaaRecord aaa    = new AaaaRecord(ARSoft.Tools.Net.DomainName.Parse("example.com"), 0, System.Net.IPAddress.Parse("127.0.0.1"));
            string     straaa = aaa.ToString();

            System.Console.WriteLine(straaa);


            // DnsRecordBase drb = null;
            // DnsMessage msg = DnsMessage.Parse(new byte[] { });
            // DnsKeyFlags flags = DnsKeyFlags.SecureEntryPoint;

            KeyPairRecord ZSK_key = CreateSigningKey(DnsSecAlgorithm.EccGost, DnsKeyFlags.Zone, 512);
            KeyPairRecord keyPair = CreateSigningKey(DnsSecAlgorithm.EccGost, DnsKeyFlags.SecureEntryPoint, 512);


            byte[] zsPub  = Org.BouncyCastle.X509.SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(ZSK_key.KeyPair.Public).GetDerEncoded();
            byte[] zsPriv = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.KeyPair.Private).GetDerEncoded();

            bool bPub  = System.Linq.Enumerable.SequenceEqual(ZSK_key.PublicKey, zsPub);
            bool bPriv = System.Linq.Enumerable.SequenceEqual(ZSK_key.PrivateKey, zsPriv);

            System.Console.WriteLine("Pub; {0}\t Priv: {1}", bPub, bPriv);


            // Private key only necessary when signing, now when publishing...
            DnsKeyRecord dnsKey = new DnsKeyRecord(
                ARSoft.Tools.Net.DomainName.Parse("example.com") // Name: It defines the hostname of a record and whether the hostname will be appended to the label.
                // Fully qualified hostnames terminated by a period will not append the origin.
                , RecordClass.Any
                , 60 // ttl The time-to-live in seconds. It specifies how long a resolver is supposed to cache or remember the DNS query
                     // before the query expires and a new one needs to be done.
                , keyPair.Flags
                , 3                 // Fixed value of 3 (for backwards compatibility)
                , keyPair.Algorithm // The public key's cryptographic algorithm.
                , keyPair.PublicKey //  new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } // Public key data.
                , keyPair.PrivateKey
                );



            string strDNSKey = dnsKey.ToString();

            // dnsKey.CalculateKeyTag()
            System.Console.WriteLine(strDNSKey);
            // example.com. 60 * DNSKEY 256 3 8 AQIDBAUGBwgJ



            System.Collections.Generic.List <DnsRecordBase> records = new System.Collections.Generic.List <DnsRecordBase>();
            records.Add(aaa);



            RrSigRecord rrsig1   = RrSigRecord.SignRecord(records, dnsKey, System.DateTime.UtcNow, System.DateTime.UtcNow.AddDays(30));
            string      strRRsig = rrsig1.ToString();

            // rrsig1.Signature
            System.Console.WriteLine(strRRsig);

            // example.com. 0 IN RRSIG AAAA 12 2 0 20200122193048 20191223193048 46296 example.com. 9aCosjMmgc1iL4jNavgPAA5NXRp5jukyKxb9vCA8PNoz1d4LjaTjfURxnKhX97KkkTdSW0tUoeYgBK7t/qjOFg==

            RrSigRecord rrsig = new RrSigRecord(
                ARSoft.Tools.Net.DomainName.Parse("example.com")   // Name of the digitally signed RRs
                , RecordClass.Any
                , 60                                               // ttl The time-to-live in seconds. It specifies how long a resolver is supposed to cache or remember the DNS query
                                                                   // before the query expires and a new one needs to be done.
                , RecordType.A                                     // Type Covered: DNS record type that this signature covers.
                , DnsSecAlgorithm.EccGost                          // Cryptographic algorithm used to create the signature.
                , 4                                                // Labels: Number of labels in the original RRSIG-record name (used to validate wildcards).
                , 0                                                // Original TTL: TTL value of the covered record set.
                , System.DateTime.Now.AddMinutes(1)                // Signature Expiration: When the signature expires.
                , System.DateTime.Now                              // Signature Inception: When the signature was created.
                , 0                                                // Key Tag: A short numeric value which can help quickly identify the DNSKEY-record which can be used to validate this signature.
                                                                   // identifiziert den unterzeichnenden DNSKEY, um zwischen mehreren Signaturen zu unterscheiden (engl. key tag)
                , ARSoft.Tools.Net.DomainName.Parse("example.com") // Signer's Name: Name of the DNSKEY-record which can be used to validate this signature.
                , new byte[] { 1, 2, 3 }                           // Signature: Cryptographic signature.  (Base64)
                );



            DsRecord signedDsRec    = new DsRecord(dnsKey, 0, keyPair.Digest);
            string   strSignedDsRec = signedDsRec.ToString();

            System.Console.WriteLine(strSignedDsRec);
            // signedDsRec.Digest
            // example.com. 0 * DS 24280 12 3 C453FBE75917C8A07BB767230463FA6C271E21D3D92F1ACCC538A194A7C41CC8


            DsRecord dsRec = new DsRecord(
                ARSoft.Tools.Net.DomainName.Parse("example.com")   // Name: It defines the hostname of a record and whether the hostname will be appended to the label.
                // Fully qualified hostnames terminated by a period will not append the origin.
                , RecordClass.Any
                , 60                        // ttl The time-to-live in seconds. It specifies how long a resolver is supposed to cache or remember the DNS query
                     // before the query expires and a new one needs to be done.
                , 0                         // Key Tag: A short numeric value which can help quickly identify the referenced DNSKEY-record.
                , DnsSecAlgorithm.RsaSha256 // The algorithm of the referenced DNSKEY-record.
                , DnsSecDigestType.Sha256   // Digest Type: Cryptographic hash algorithm used to create the Digest value.
                , new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0xFF } // A cryptographic hash value of the referenced DNSKEY-record.
                );

            // dsRec.Digest
            string strDsRec = dsRec.ToString();

            System.Console.WriteLine(strDsRec);
            // example.com. 60 * DS 0 8 2 0102030405060708090AFF


            string strDS = dsRec.ToString();

            System.Console.WriteLine(strDS);
            // . 0 IN AAAA 127.0.0.1 // aaa
            // example.com. 0 IN AAAA 127.0.0.1
            // ds:
            // example.com. 60 * DS 0 8 2 010203
            // example.com. 60 * DS 0 8 2 010203040506070809
            // example.com. 60 * DS 0 8 2 0102030405060708090AFF



            // rec.Algorithm

            string key = @"AQPSKmynfzW4kyBv015MUG2DeIQ3
              Cbl+BBZH4b/0PY1kxkmvHjcZc8no
              kfzj31GajIQKY+5CptLr3buXA10h
              WqTkF7H6RfoRqXQeogmMHfpftf6z
              Mv1LyBUgia7za6ZEzOJBOztyvhjL
              742iU/TpPSEDhm2SNKLijfUppn1U
              aNvv4w== ";


            byte[] keyBytes = Base64ToByteArray(key);



            string signature = @"2BB183AF5F22588179A53B0A98631FAD1A292118";


            // ArsoftTestServer.KeyConversion.fromPublicKey()
            PublicKey pk = ArsoftTestServer.KeyConversionTo.toPublicKey(keyBytes, DnsSecAlgorithm.RsaSha1);

            System.Console.WriteLine(pk);

            byte[] generatedKeyBytes = ArsoftTestServer.KeyConversion.fromPublicKey(pk, DnsSecAlgorithm.RsaSha1);

            // ArsoftTestServer.Resolvers.Test4();
            // ArsoftTestServer.SimpleServer.Test();

            System.Console.WriteLine(System.Environment.NewLine);
            System.Console.WriteLine(" --- Press any key to continue --- ");
            System.Console.ReadKey();
        }