github.com/creativeprojects/go-selfupdate@v1.2.0/update/doc.go (about)

     1  /*
     2  Package update provides functionality to implement secure, self-updating Go programs (or other single-file targets).
     3  
     4  Basic Example
     5  
     6  This example shows how to update a program remotely from a URL.
     7  
     8  	import (
     9  		"fmt"
    10  		"net/http"
    11  
    12  		"github.com/creativeprojects/go-selfupdate/update"
    13  	)
    14  
    15  	func doUpdate(url string) error {
    16  		// request the new file
    17  		resp, err := http.Get(url)
    18  		if err != nil {
    19  			return err
    20  		}
    21  		defer resp.Body.Close()
    22  		err := update.Apply(resp.Body, update.Options{})
    23  		if err != nil {
    24  			if rerr := update.RollbackError(err); rerr != nil {
    25  				fmt.Println("Failed to rollback from bad update: %v", rerr)
    26  			}
    27  		}
    28  		return err
    29  	}
    30  
    31  
    32  Checksum Verification
    33  
    34  Updating executable code on a computer can be a dangerous operation unless you
    35  take the appropriate steps to guarantee the authenticity of the new code. While
    36  checksum verification is important, it should always be combined with signature
    37  verification (next section) to guarantee that the code came from a trusted party.
    38  
    39  go-update validates SHA256 checksums by default, but this is pluggable via the Hash
    40  property on the Options struct.
    41  
    42  This example shows how to guarantee that the newly-updated binary is verified to
    43  have an appropriate checksum (that was otherwise retrieved via a secure channel)
    44  specified as a hex string.
    45  
    46  	import (
    47  		"crypto"
    48  		_ "crypto/sha256"
    49  		"encoding/hex"
    50  		"io"
    51  
    52  		"github.com/creativeprojects/go-selfupdate/update"
    53  	)
    54  
    55  	func updateWithChecksum(binary io.Reader, hexChecksum string) error {
    56  		checksum, err := hex.DecodeString(hexChecksum)
    57  		if err != nil {
    58  			return err
    59  		}
    60  		err = update.Apply(binary, update.Options{
    61  			Hash: crypto.SHA256, 	// this is the default, you don't need to specify it
    62  			Checksum: checksum,
    63  		})
    64  		if err != nil {
    65  			// error handling
    66  		}
    67  		return err
    68  	}
    69  
    70  Cryptographic Signature Verification
    71  
    72  Cryptographic verification of new code from an update is an extremely important way to guarantee the
    73  security and integrity of your updates.
    74  
    75  Verification is performed by validating the signature of a hash of the new file.
    76  
    77  This example shows how to add signature verification to your updates. To make all of this work
    78  an application distributor must first create a public/private key pair and embed the public key
    79  into their application. When they issue a new release, the issuer must sign the new executable file
    80  with the private key and distribute the signature along with the update.
    81  
    82  	import (
    83  		"crypto"
    84  		_ "crypto/sha256"
    85  		"encoding/hex"
    86  		"io"
    87  
    88  		"github.com/creativeprojects/go-selfupdate/update"
    89  	)
    90  
    91  	var publicKey = []byte(`
    92  	-----BEGIN PUBLIC KEY-----
    93  	MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtrVmBxQvheRArXjg2vG1xIprWGuCyESx
    94  	MMY8pjmjepSy2kuz+nl9aFLqmr+rDNdYvEBqQaZrYMc6k29gjvoQnQ==
    95  	-----END PUBLIC KEY-----
    96  	`)
    97  
    98  	func verifiedUpdate(binary io.Reader, hexChecksum, hexSignature string) {
    99  		checksum, err := hex.DecodeString(hexChecksum)
   100  		if err != nil {
   101  			return err
   102  		}
   103  		signature, err := hex.DecodeString(hexSignature)
   104  		if err != nil {
   105  			return err
   106  		}
   107  		opts := update.Options{
   108  			Checksum: checksum,
   109  			Signature: signature,
   110  			Hash: crypto.SHA256, 	               // this is the default, you don't need to specify it
   111  			Verifier: update.NewECDSAVerifier(),   // this is the default, you don't need to specify it
   112  		}
   113  		err = opts.SetPublicKeyPEM(publicKey)
   114  		if err != nil {
   115  			return err
   116  		}
   117  		err = update.Apply(binary, opts)
   118  		if err != nil {
   119  			// error handling
   120  		}
   121  		return err
   122  	}
   123  
   124  
   125  */
   126  package update