github.com/himawarisunflower/go-update@v0.0.0-20210917073417-3bee296db6a2/doc.go (about)

     1  /*
     2  Package update provides functionality to implement secure, self-updating Go programs (or other single-file targets).
     3  
     4  For complete updating solutions please see Equinox (https://equinox.io) and go-tuf (https://github.com/flynn/go-tuf).
     5  
     6  Basic Example
     7  
     8  This example shows how to update a program remotely from a URL.
     9  
    10  	import (
    11  		"fmt"
    12  		"net/http"
    13  
    14  		"github.com/inconshreveable/go-update"
    15  	)
    16  
    17  	func doUpdate(url string) error {
    18  		// request the new file
    19  		resp, err := http.Get(url)
    20  		if err != nil {
    21  			return err
    22  		}
    23  		defer resp.Body.Close()
    24  		err := update.Apply(resp.Body, update.Options{})
    25  		if err != nil {
    26  			if rerr := update.RollbackError(err); rerr != nil {
    27  				fmt.Println("Failed to rollback from bad update: %v", rerr)
    28  			}
    29  		}
    30  		return err
    31  	}
    32  
    33  
    34  Binary Patching
    35  
    36  Go binaries can often be large. It can be advantageous to only ship a binary patch to a client
    37  instead of the complete program text of a new version.
    38  
    39  This example shows how to update a program with a bsdiff binary patch. Other patch formats
    40  may be applied by implementing the Patcher interface.
    41  
    42  	import (
    43  		"encoding/hex"
    44  		"io"
    45  
    46  		"github.com/inconshreveable/go-update"
    47  	)
    48  
    49  	func updateWithPatch(patch io.Reader) error {
    50  		err := update.Apply(patch, update.Options{
    51  			Patcher: update.NewBSDiffPatcher()
    52  		})
    53  		if err != nil {
    54  			// error handling
    55  		}
    56  		return err
    57  	}
    58  
    59  Checksum Verification
    60  
    61  Updating executable code on a computer can be a dangerous operation unless you
    62  take the appropriate steps to guarantee the authenticity of the new code. While
    63  checksum verification is important, it should always be combined with signature
    64  verification (next section) to guarantee that the code came from a trusted party.
    65  
    66  go-update validates SHA256 checksums by default, but this is pluggable via the Hash
    67  property on the Options struct.
    68  
    69  This example shows how to guarantee that the newly-updated binary is verified to
    70  have an appropriate checksum (that was otherwise retrived via a secure channel)
    71  specified as a hex string.
    72  
    73  	import (
    74  		"crypto"
    75  		_ "crypto/sha256"
    76  		"encoding/hex"
    77  		"io"
    78  
    79  		"github.com/inconshreveable/go-update"
    80  	)
    81  
    82  	func updateWithChecksum(binary io.Reader, hexChecksum string) error {
    83  		checksum, err := hex.DecodeString(hexChecksum)
    84  		if err != nil {
    85  			return err
    86  		}
    87  		err = update.Apply(binary, update.Options{
    88  			Hash: crypto.SHA256, 	// this is the default, you don't need to specify it
    89  			Checksum: checksum,
    90  		})
    91  		if err != nil {
    92  			// error handling
    93  		}
    94  		return err
    95  	}
    96  
    97  Cryptographic Signature Verification
    98  
    99  Cryptographic verification of new code from an update is an extremely important way to guarantee the
   100  security and integrity of your updates.
   101  
   102  Verification is performed by validating the signature of a hash of the new file. This
   103  means nothing changes if you apply your update with a patch.
   104  
   105  This example shows how to add signature verification to your updates. To make all of this work
   106  an application distributor must first create a public/private key pair and embed the public key
   107  into their application. When they issue a new release, the issuer must sign the new executable file
   108  with the private key and distribute the signature along with the update.
   109  
   110  	import (
   111  		"crypto"
   112  		_ "crypto/sha256"
   113  		"encoding/hex"
   114  		"io"
   115  
   116  		"github.com/inconshreveable/go-update"
   117  	)
   118  
   119  	var publicKey = []byte(`
   120  	-----BEGIN PUBLIC KEY-----
   121  	MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtrVmBxQvheRArXjg2vG1xIprWGuCyESx
   122  	MMY8pjmjepSy2kuz+nl9aFLqmr+rDNdYvEBqQaZrYMc6k29gjvoQnQ==
   123  	-----END PUBLIC KEY-----
   124  	`)
   125  
   126  	func verifiedUpdate(binary io.Reader, hexChecksum, hexSignature string) {
   127  		checksum, err := hex.DecodeString(hexChecksum)
   128  		if err != nil {
   129  			return err
   130  		}
   131  		signature, err := hex.DecodeString(hexSignature)
   132  		if err != nil {
   133  			return err
   134  		}
   135  		opts := update.Options{
   136  			Checksum: checksum,
   137  			Signature: signature,
   138  			Hash: crypto.SHA256, 	                 // this is the default, you don't need to specify it
   139  			Verifier: update.NewECDSAVerifier(),   // this is the default, you don't need to specify it
   140  		}
   141  		err = opts.SetPublicKeyPEM(publicKey)
   142  		if err != nil {
   143  			return err
   144  		}
   145  		err = update.Apply(binary, opts)
   146  		if err != nil {
   147  			// error handling
   148  		}
   149  		return err
   150  	}
   151  
   152  
   153  Building Single-File Go Binaries
   154  
   155  In order to update a Go application with go-update, you must distributed it as a single executable.
   156  This is often easy, but some applications require static assets (like HTML and CSS asset files or TLS certificates).
   157  In order to update applications like these, you'll want to make sure to embed those asset files into
   158  the distributed binary with a tool like go-bindata (my favorite): https://github.com/jteeuwen/go-bindata
   159  
   160  Non-Goals
   161  
   162  Mechanisms and protocols for determining whether an update should be applied and, if so, which one are
   163  out of scope for this package. Please consult go-tuf (https://github.com/flynn/go-tuf) or Equinox (https://equinox.io)
   164  for more complete solutions.
   165  
   166  go-update only works for self-updating applications that are distributed as a single binary, i.e.
   167  applications that do not have additional assets or dependency files.
   168  Updating application that are distributed as mutliple on-disk files is out of scope, although this
   169  may change in future versions of this library.
   170  
   171  */
   172  package update