canarytail

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 24, 2021 License: GPL-3.0 Imports: 12 Imported by: 0

README

CanaryTail CLI

CanaryTail CLI is a simple proof-of-concept implementation of the CanaryTail standard

Installation

Windows:
$Env:GOOS="windows"; $Env:GOARCH="amd64"; go build -o canarytail-windows-amd64.exe ./cmd/
$Env:GOOS="linux"; $Env:GOARCH="amd64"; go build -o canarytail-linux-amd64 ./cmd/
$Env:GOOS="darwin"; $Env:GOARCH="amd64"; go build -o canarytail-darwin-amd64 ./cmd/
OS X & Linux:

Skip this step if you already know how to use go

In order to build, make sure you have go installed and the GOPATH set to its location. It will likely be /usr/local/go. Replace the example below with your go location.

export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin

Build the project from the source folder for this canarytail client repo

 go build ./cmd/canarytail.go

Run it via ./canarytail, which should return:

Usage: ./canarytail command [SUBCOMMAND] [OPTIONS]

Commands:
  help		                  Display this help message or help on a command

  init		                  Initialize config and keys to $CANARY_HOME
  key

      This command is for manipulating cryptographic keys.

      new ALIAS               Generates a new key for signing canaries and saves
                              to $CANARY_HOME/ALIAS

  canary

      This command is for manipulating canaries.

      new ALIAS [--OPTIONS]
                              Generates a new canary, signs it using the key located
                              in $CANARY_HOME/ALIAS, and saves to that same path.

                              Codes provided in OPTIONS will be removed from the canary,
                              signifying that event has triggered the canary.

      update ALIAS [--OPTIONS]
                              Updates the existing canary named ALIAS. If no OPTIONS
                              are provided, it merely updates the signature date. If
                              no EXPIRY is provided, it reuses the previous value
                              (e.g. renewing for a month).

                              Codes provided in OPTIONS will be removed from the canary,
                              signifying that event has triggered the canary.
                              

      Valid OPTIONS:

      --expiry:#              Expires in # minutes from now (default: 43200, one month)
      --cease                 Court order to cease operations
      --duress                Under duress (coercion, blackmail, etc)
      --gag                   Gag order received
      --raid                  Raided, but data unlikely compromised
      --seize                 Hardware or data seized, unlikely compromised
      --subp                  Subpoena received
      --trap                  Trap and trace order received
      --war                   Warrant received
      --xcred                 Compromised credentials
      --xopers                Operations compromised

      validate [URI]              Validates a canary's signature

  version	                  Show version and exit

Environment:
  CANARY_HOME	Location of canarytail config and files (default: $PWD)


Usage examples:

New canary signing key               ./canarytail key new mydomain
New canary with defaults             ./canarytail canary new mydomain       
Renew existing canary 30 more days   ./canarytail canary update mydomain
Trigger canary for warrant           ./canarytail canary update mydomain --WAR
Validate a canary on a site          ./canarytail canary validate https://mydomain/canary.json
Validate a canary locally            ./canarytail canary validate ~/canary.json

Contributing

  1. Fork it (https://github.com/canarytail/client/fork)
  2. Create your feature branch (git checkout -b feature/fooBar)
  3. Commit your changes (git commit -am 'Add some fooBar')
  4. Push to the branch (git push origin feature/fooBar)
  5. Create a new Pull Request

Documentation

Index

Constants

View Source
const StandardVersion string = "0.1"

StandardVersion represents the current standard version being used by this library

View Source
const TimestampLayout string = time.RFC3339

TimestampLayout defines the timestamp layout used in the standard const TimestampLayout string = "2006-01-02T15:04:05.000" // time.RFC3339 should be preferred (what we have plus Z)

Variables

This section is empty.

Functions

func AllCodes

func AllCodes() []string

AllCodes lists all Canary codes TODO: support multiple standard versions

func FormatBlockChainBlockHash

func FormatBlockChainBlockHash(blockHash []byte) string

FormatBlockChainBlockHash formats a block hash in the standartd string format

func FormatKey

func FormatKey(key []byte) string

FormatKey formats a key into a base64 string

func GenerateKeyPair

func GenerateKeyPair() (ed25519.PublicKey, ed25519.PrivateKey, error)

GenerateKeyPair generates an Ed25519 key pair for signatures. See https://ed25519.cr.yp.to/.

These functions are also compatible with the “Ed25519” function defined in RFC 8032. However, unlike RFC 8032's formulation, this package's private key representation includes a public key suffix to make multiple signing operations with the same key more efficient. This package refers to the RFC 8032 private key as the “seed”.

func GetLastBlockChainBlockHash

func GetLastBlockChainBlockHash() []byte

GetLastBlockChainBlockHash retrieves the latest block hash from the BlockChain Data API

func GetLastBlockChainBlockHashFormatted

func GetLastBlockChainBlockHashFormatted() string

GetLastBlockChainBlockHashFormatted retrieves the latest block hash from the BlockChain Data API, in the standard string format

func InverseCodes

func InverseCodes(codesToFlag []string) []string

InverseCodes returns the missing codes from the standard, given a list of codes

func ParsePrivateKey

func ParsePrivateKey(privateKey string) (ed25519.PrivateKey, error)

ParsePrivateKey parses a private key in string form

func ParsePublicKey

func ParsePublicKey(publicKey string) (ed25519.PublicKey, error)

ParsePublicKey parses a public key in string form

func SignString

func SignString(formattedCanary string, privateKey ed25519.PrivateKey) []byte

SignString signs a Canary given a private key

func StructToMap

func StructToMap(obj interface{}) (newMap map[string]interface{}, err error)

StructToMap converts a struct to a map while maintaining the json alias as keys

func ValidateSignatureString

func ValidateSignatureString(formattedCanary string, signature []byte, publicKey ed25519.PublicKey) bool

ValidateSignatureString validates a Canary's signature given the corresponding public key

Types

type BlockInfo

type BlockInfo struct {
	Hash          string `json:"hash"`
	PreviousBlock string `json:"prev_block"`
	Time          int64  `json:"time"`
	Bits          int64  `json:"bits"`
	BlockIndex    int    `json:"block_index"`
	Height        int    `json:"height"`
}

BlockInfo represents a block in the BlockChain Data API https://www.blockchain.com/api/blockchain_api

{
    "hash":"0000000000000bae09a7a393a8acded75aa67e46cb81f7acaa5ad94f9eacd103",
    "ver":1,
    "prev_block":"00000000000007d0f98d9edca880a6c124e25095712df8952e0439ac7409738a",
    "mrkl_root":"935aa0ed2e29a4b81e0c995c39e06995ecce7ddbebb26ed32d550a72e8200bf5",
    "time":1322131230,
    "bits":437129626,
    "nonce":2964215930,
    "n_tx":22,
    "size":9195,
    "block_index":818044,
    "main_chain":true,
    "height":154595,
    "received_time":1322131301,
    "relayed_by":"108.60.208.156",
    "tx":[--Array of Transactions--]
}

func GetBlockInfo

func GetBlockInfo(blockHash []byte) (BlockInfo, error)

GetBlockInfo retrieves the block information from the BlockChain Data API

type Canary

type Canary struct {
	Claim      CanaryClaim                    `json:"canary"`
	Signatures map[string]*CanarySignatureSet `json:"signatures"` // the key of the map is the public key that signs the signature set
}

Canary represents a Canary, with its claims and its signature(s)

func Read

func Read(url string) (Canary, error)

Read parses a canary from a URL or a local path

func (Canary) ExiprationTimestamp

func (c Canary) ExiprationTimestamp() time.Time

ExiprationTimestamp parses the expiration timestamp within this canary claims

func (Canary) Format

func (c Canary) Format() string

Format gets the JSON representation of the canary

func (Canary) IsExpired

func (c Canary) IsExpired() bool

IsExpired checks whether the canary is expired

func (Canary) MissingCodes

func (c Canary) MissingCodes() []string

MissingCodes gets the missing codes from this Canary's claims

func (Canary) PanicKey

func (c Canary) PanicKey() []byte

PanicKey returns the most current panic key of the canary

func (Canary) ReleaseTimestamp

func (c Canary) ReleaseTimestamp() time.Time

ReleaseTimestamp parses the expiration timestamp within this canary claims

func (*Canary) Sign

func (c *Canary) Sign(privKey, pubKey []byte) (err error)

Sign generates the signatures of all the canary claims for a given public key

func (Canary) Validate

func (c Canary) Validate() (bool, error)

Validate validates if the Canary claims indicate some sort of issue

func (*Canary) ValidateSignatures

func (c *Canary) ValidateSignatures(pubKey []byte) bool

ValidateSignatures validates the signatures of a canary for a given public key

type CanaryClaim

type CanaryClaim struct {
	Domain     string   `json:"domain"`
	PublicKeys []string `json:"pubkeys"`
	PanicKey   string   `json:"panickey"`
	Version    string   `json:"version"`
	Release    string   `json:"release"` // 2019-03-06T22:23:09.963
	Expiry     string   `json:"expiry"`  // 2019-03-06T22:23:09.963
	Freshness  string   `json:"freshness"`
	Codes      []string `json:"codes"`
}

CanaryClaim the claims that conform this canary

type CanarySignature

type CanarySignature string

CanarySignature we will keep this as a string for now, in the future it will support several signatures

type CanarySignatureSet

type CanarySignatureSet struct {
	Domain     CanarySignature `json:"domain"`
	PublicKeys CanarySignature `json:"pubkeys"`
	PanicKey   CanarySignature `json:"panickey"`
	Version    CanarySignature `json:"version"`
	Release    CanarySignature `json:"release"`
	Expiry     CanarySignature `json:"expiry"`
	Freshness  CanarySignature `json:"freshness"`
	Codes      CanarySignature `json:"codes"`
}

type CanarySignatureValidator

type CanarySignatureValidator struct {
	Canary    Canary
	PublicKey string
}

CanarySignatureValidator validates an ECDSA (​Curve25519​) set of signatures for a given canary and a public key

func (*CanarySignatureValidator) Validate

func (v *CanarySignatureValidator) Validate() (bool, error)

Validate a signature set for a given public key

type CanaryValidator

type CanaryValidator struct {
	Canary         Canary
	Validators     []CanarySignatureValidator
	PanicValidator CanarySignatureValidator
}

CanaryValidator validates a canary

func NewCanaryValidator

func NewCanaryValidator(canary Canary) (validator *CanaryValidator)

NewCanaryValidator instantiates a CanaryValidator

func (*CanaryValidator) Validate

func (v *CanaryValidator) Validate() (bool, error)

Validate validates all the registered validators (one per public key in the canary plus the panic key)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL