From 9c0c81b9e15362c09ba8dc29e7d93299dc2745de Mon Sep 17 00:00:00 2001 From: iamsurfing Date: Wed, 2 Jun 2021 23:46:50 +0800 Subject: [PATCH 1/3] Update README.md Add import to example code --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index e62d962..2f94ca8 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,10 @@ You can also send a DNSCrypt request using a command that does not require stamp ### Client ```go +import ( + "github.com/ameshkov/dnscrypt/v2" +) + // AdGuard DNS stamp stampStr := "sdns://AQMAAAAAAAAAETk0LjE0MC4xNC4xNDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20" @@ -166,6 +170,10 @@ reply, err := c.Exchange(&req, resolverInfo) ## Server ```go +import ( + "github.com/ameshkov/dnscrypt/v2" +) + // Prepare the test DNSCrypt server config rc, err := dnscrypt.GenerateResolverConfig("example.org", nil) if err != nil { From 6488a78ac5385ad41613fa53bd3fd5fbac0b2e05 Mon Sep 17 00:00:00 2001 From: iamsurfing Date: Tue, 8 Jun 2021 12:35:28 +0800 Subject: [PATCH 2/3] SetCertInfo & SetCertInfoStamp --- client.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/client.go b/client.go index ebf1574..d4c5a54 100644 --- a/client.go +++ b/client.go @@ -31,6 +31,23 @@ type ResolverInfo struct { SharedKey [keySize]byte // Shared key that is to be used to encrypt/decrypt messages } +// SetCertInfo and validates DNSCrypt certificate from the given dns message +// Data received during this call is then used for DNS requests encryption/decryption +// stampStr is an sdns:// address which is parsed using go-dnsstamps package +func (c *Client) SetCertInfo(stampStr string,r dns.Msg) (*ResolverInfo, error) { + stamp, err := dnsstamps.NewServerStampFromString(stampStr) + if err != nil { + // Invalid SDNS stamp + return nil, err + } + + if stamp.Proto != dnsstamps.StampProtoTypeDNSCrypt { + return nil, ErrInvalidDNSStamp + } + + return c.SetCertInfoStamp(stamp,r) +} + // Dial fetches and validates DNSCrypt certificate from the given server // Data received during this call is then used for DNS requests encryption/decryption // stampStr is an sdns:// address which is parsed using go-dnsstamps package @@ -48,6 +65,35 @@ func (c *Client) Dial(stampStr string) (*ResolverInfo, error) { return c.DialStamp(stamp) } + +// SetCertInfoStamp set and validates DNSCrypt certificate from the given server +// Data received during this call is then used for DNS requests encryption/decryption +func (c *Client) SetCertInfoStamp(stamp dnsstamps.ServerStamp,r dns.Msg) (*ResolverInfo, error) { + resolverInfo := &ResolverInfo{} + + // Generate the secret/public pair + resolverInfo.SecretKey, resolverInfo.PublicKey = generateRandomKeyPair() + + // Set the provider properties + resolverInfo.ServerPublicKey = stamp.ServerPk + resolverInfo.ServerAddress = stamp.ServerAddrStr + resolverInfo.ProviderName = stamp.ProviderName + + cert, err := c.fetchCert(stamp,r) + if err != nil { + return nil, err + } + resolverInfo.ResolverCert = cert + + // Compute shared key that we'll use to encrypt/decrypt messages + sharedKey, err := computeSharedKey(cert.EsVersion, &resolverInfo.SecretKey, &cert.ResolverPk) + if err != nil { + return nil, err + } + resolverInfo.SharedKey = sharedKey + return resolverInfo, nil +} + // DialStamp fetches and validates DNSCrypt certificate from the given server // Data received during this call is then used for DNS requests encryption/decryption func (c *Client) DialStamp(stamp dnsstamps.ServerStamp) (*ResolverInfo, error) { @@ -61,7 +107,7 @@ func (c *Client) DialStamp(stamp dnsstamps.ServerStamp) (*ResolverInfo, error) { resolverInfo.ServerAddress = stamp.ServerAddrStr resolverInfo.ProviderName = stamp.ProviderName - cert, err := c.fetchCert(stamp) + cert, err := c.fetchCertPlaintext(stamp) if err != nil { return nil, err } @@ -202,14 +248,12 @@ func (c *Client) decrypt(b []byte, resolverInfo *ResolverInfo) (*dns.Msg, error) } return res, nil } - -// fetchCert loads DNSCrypt cert from the specified server -func (c *Client) fetchCert(stamp dnsstamps.ServerStamp) (*Cert, error) { +//fetchCertPlaintext loads DNSCrypt record from the specified server +func (c *Client) fetchCertPlaintext(stamp dnsstamps.ServerStamp) (*Cert, error){ providerName := stamp.ProviderName if !strings.HasSuffix(providerName, ".") { providerName = providerName + "." } - query := new(dns.Msg) query.SetQuestion(providerName, dns.TypeTXT) client := dns.Client{Net: c.Net, UDPSize: uint16(maxQueryLen), Timeout: c.Timeout} @@ -221,7 +265,15 @@ func (c *Client) fetchCert(stamp dnsstamps.ServerStamp) (*Cert, error) { if r.Rcode != dns.RcodeSuccess { return nil, ErrFailedToFetchCert } + return c.fetchCert(stamp,*r) +} +// fetchCert set DNSCrypt cert +func (c *Client) fetchCert(stamp dnsstamps.ServerStamp,r dns.Msg) (*Cert, error) { + providerName := stamp.ProviderName + if !strings.HasSuffix(providerName, ".") { + providerName = providerName + "." + } var certErr error currentCert := &Cert{} foundValid := false From 830c7dcabe58f07cbae35b077828562ce3bafefc Mon Sep 17 00:00:00 2001 From: iamsurfing Date: Tue, 8 Jun 2021 17:51:15 +0800 Subject: [PATCH 3/3] Update client.go --- client.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client.go b/client.go index d4c5a54..4772969 100644 --- a/client.go +++ b/client.go @@ -34,7 +34,7 @@ type ResolverInfo struct { // SetCertInfo and validates DNSCrypt certificate from the given dns message // Data received during this call is then used for DNS requests encryption/decryption // stampStr is an sdns:// address which is parsed using go-dnsstamps package -func (c *Client) SetCertInfo(stampStr string,r dns.Msg) (*ResolverInfo, error) { +func (c *Client) SetCertInfo(stampStr string, r dns.Msg) (*ResolverInfo, error) { stamp, err := dnsstamps.NewServerStampFromString(stampStr) if err != nil { // Invalid SDNS stamp @@ -45,7 +45,7 @@ func (c *Client) SetCertInfo(stampStr string,r dns.Msg) (*ResolverInfo, error) { return nil, ErrInvalidDNSStamp } - return c.SetCertInfoStamp(stamp,r) + return c.SetCertInfoStamp(stamp, r) } // Dial fetches and validates DNSCrypt certificate from the given server @@ -65,10 +65,9 @@ func (c *Client) Dial(stampStr string) (*ResolverInfo, error) { return c.DialStamp(stamp) } - // SetCertInfoStamp set and validates DNSCrypt certificate from the given server // Data received during this call is then used for DNS requests encryption/decryption -func (c *Client) SetCertInfoStamp(stamp dnsstamps.ServerStamp,r dns.Msg) (*ResolverInfo, error) { +func (c *Client) SetCertInfoStamp(stamp dnsstamps.ServerStamp, r dns.Msg) (*ResolverInfo, error) { resolverInfo := &ResolverInfo{} // Generate the secret/public pair @@ -79,7 +78,7 @@ func (c *Client) SetCertInfoStamp(stamp dnsstamps.ServerStamp,r dns.Msg) (*Resol resolverInfo.ServerAddress = stamp.ServerAddrStr resolverInfo.ProviderName = stamp.ProviderName - cert, err := c.fetchCert(stamp,r) + cert, err := c.setCertInfo(stamp, r) if err != nil { return nil, err } @@ -107,7 +106,7 @@ func (c *Client) DialStamp(stamp dnsstamps.ServerStamp) (*ResolverInfo, error) { resolverInfo.ServerAddress = stamp.ServerAddrStr resolverInfo.ProviderName = stamp.ProviderName - cert, err := c.fetchCertPlaintext(stamp) + cert, err := c.fetchCert(stamp) if err != nil { return nil, err } @@ -248,8 +247,9 @@ func (c *Client) decrypt(b []byte, resolverInfo *ResolverInfo) (*dns.Msg, error) } return res, nil } + //fetchCertPlaintext loads DNSCrypt record from the specified server -func (c *Client) fetchCertPlaintext(stamp dnsstamps.ServerStamp) (*Cert, error){ +func (c *Client) fetchCert(stamp dnsstamps.ServerStamp) (*Cert, error) { providerName := stamp.ProviderName if !strings.HasSuffix(providerName, ".") { providerName = providerName + "." @@ -265,11 +265,11 @@ func (c *Client) fetchCertPlaintext(stamp dnsstamps.ServerStamp) (*Cert, error){ if r.Rcode != dns.RcodeSuccess { return nil, ErrFailedToFetchCert } - return c.fetchCert(stamp,*r) + return c.setCertInfo(stamp, *r) } // fetchCert set DNSCrypt cert -func (c *Client) fetchCert(stamp dnsstamps.ServerStamp,r dns.Msg) (*Cert, error) { +func (c *Client) setCertInfo(stamp dnsstamps.ServerStamp, r dns.Msg) (*Cert, error) { providerName := stamp.ProviderName if !strings.HasSuffix(providerName, ".") { providerName = providerName + "."