sign

package
v3.2.3-jaredallard.2 Latest Latest
Warning

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

Go to latest
Published: Feb 25, 2025 License: GPL-2.0, GPL-2.0 Imports: 33 Imported by: 0

README

GoDoc

sigtool/sign - Ed25519 signature calculation and verification

This is a small library that makes it easier to create and serialize Ed25519 keys, and sign, verify files using those keys. The library uses mmap(2) to read and process very large files.

The companion program sigtool uses this library.

License

GPL v2.0

Documentation

Overview

Package sign implements Ed25519 signing, verification on files. It builds upon golang.org/x/crypto/ed25519 by adding methods for serializing and deserializing Ed25519 private & public keys.

It can sign and verify very large files - it prehashes the files with SHA-512 and then signs the SHA-512 checksum. The keys and signatures are YAML files and so, human readable.

It can encrypt files for multiple recipients - each of whom is identified by their Ed25519 public key. The encryption by default generates ephmeral Curve25519 keys and creates pair-wise shared secret for each recipient of the encrypted file. The caller can optionally use a specific secret key during the encryption process - this has the benefit of also authenticating the sender (and the receiver can verify the sender if they possess the corresponding public key).

The sign, verify, encrypt, decrypt operations can use OpenSSH Ed25519 keys *or* the keys generated by sigtool. This means, you can send encrypted files to any recipient identified by their comment in `~/.ssh/authorized_keys`.

Index

Constants

View Source
const PKHashLength = 16

Length of Ed25519 Public Key Hash

Variables

View Source
var (
	ErrClosed         = errors.New("encrypt: stream already closed")
	ErrNoKey          = errors.New("decrypt: no private key set for decryption")
	ErrEncStarted     = errors.New("encrypt: can't add new recipient after encryption has started")
	ErrDecStarted     = errors.New("decrypt: can't add new recipient after decryption has started")
	ErrEncIsStream    = errors.New("encrypt: can't use Encrypt() after using streaming I/O")
	ErrNotSigTool     = errors.New("decrypt: not a sigtool encrypted file?")
	ErrHeaderTooBig   = errors.New("decrypt: header too large (max 1048576)")
	ErrHeaderTooSmall = errors.New("decrypt: header too small (min 32)")
	ErrBadHeader      = errors.New("decrypt: header corrupted")
	ErrNoWrappedKeys  = errors.New("decrypt: no wrapped keys in encrypted file")
	ErrBadKey         = errors.New("decrypt: wrong key")
	ErrBadTrailer     = errors.New("decrypt: message integrity failed (bad trailer)")
	ErrBadSender      = errors.New("unwrap: sender verification failed")
	ErrNoSenderPK     = errors.New("unwrap: missing sender public key")

	ErrIncorrectPassword = errors.New("ssh: invalid passphrase")
	ErrNoPEMFound        = errors.New("ssh: no PEM block found")
	ErrBadPublicKey      = errors.New("ssh: malformed public key")
	ErrKeyTooShort       = errors.New("ssh: public key too short")
	ErrBadTrailers       = errors.New("ssh: trailing junk in public key")
	ErrBadFormat         = errors.New("ssh: invalid openssh private key format")
	ErrBadLength         = errors.New("ssh: private key unexpected length")
	ErrBadPadding        = errors.New("ssh: padding not as expected")
)

Functions

func Debug

func Debug(level int)

Enable debugging of this module; level > 0 elicits debug messages on os.Stderr

Types

type Decryptor

type Decryptor struct {
	pb.Header
	// contains filtered or unexported fields
}

Decryptor holds the decryption context

func NewDecryptor

func NewDecryptor(rd io.Reader) (*Decryptor, error)

Create a new decryption context and if 'pk' is given, check that it matches the sender

func (*Decryptor) AuthenticatedSender

func (d *Decryptor) AuthenticatedSender() bool

AuthenticatedSender returns true if the sender authenticated themselves (the data-encryption key is signed).

func (*Decryptor) Decrypt

func (d *Decryptor) Decrypt(wr io.Writer) error

Decrypt the file and write to 'wr'

func (*Decryptor) NewStreamReader

func (d *Decryptor) NewStreamReader() (io.Reader, error)

NewStreamReader returns an io.Reader to read from the decrypted stream

func (*Decryptor) SetPrivateKey

func (d *Decryptor) SetPrivateKey(sk *PrivateKey, senderPk *PublicKey) error

Use Private Key 'sk' to decrypt the encrypted keys in the header and optionally validate the sender

type Encryptor

type Encryptor struct {
	pb.Header
	// contains filtered or unexported fields
}

Encryptor holds the encryption context

func NewEncryptor

func NewEncryptor(sk *PrivateKey, blksize uint64) (*Encryptor, error)

Create a new Encryption context for encrypting blocks of size 'blksize'. If 'sk' is not nil, authenticate the sender to each receiver.

func (*Encryptor) AddRecipient

func (e *Encryptor) AddRecipient(pk *PublicKey) error

Add a new recipient to this encryption context.

func (*Encryptor) Encrypt

func (e *Encryptor) Encrypt(rd io.Reader, wr io.WriteCloser) error

Encrypt the input stream 'rd' and write encrypted stream to 'wr'

func (*Encryptor) NewStreamWriter

func (e *Encryptor) NewStreamWriter(wr io.WriteCloser) (io.WriteCloser, error)

NewStreamWriter begins stream encryption to an underlying destination writer 'wr'. It returns an io.WriteCloser.

type PrivateKey

type PrivateKey struct {
	Sk []byte
	// contains filtered or unexported fields
}

Private Ed25519 key

func MakePrivateKey

func MakePrivateKey(yml []byte, getpw func() ([]byte, error)) (*PrivateKey, error)

Make a private key from bytes 'yml' using optional caller provided getpw() function to read the password if needed. are assumed to be serialized version of the private key.

func NewPrivateKey

func NewPrivateKey() (*PrivateKey, error)

NewPrivateKey generates a new Ed25519 private key

func PrivateKeyFromBytes

func PrivateKeyFromBytes(buf []byte) (*PrivateKey, error)

Make a private key from 64-bytes of extended Ed25519 key

func ReadPrivateKey

func ReadPrivateKey(fn string, getpw func() ([]byte, error)) (*PrivateKey, error)

Read the private key in 'fn', optionally decrypting it using password 'pw' and create new instance of PrivateKey

func (*PrivateKey) MarshalBinary

func (sk *PrivateKey) MarshalBinary(comment string, pw []byte) ([]byte, error)

MarshalBinary marshals the private key with a caller provided passphrase 'pw' and human readable 'comment'

func (*PrivateKey) PublicKey

func (sk *PrivateKey) PublicKey() *PublicKey

Given a secret key, return the corresponding Public Key

func (*PrivateKey) Serialize

func (sk *PrivateKey) Serialize(fn, comment string, ovwrite bool, pw []byte) error

Serialize the private key to file 'fn' using human readable 'comment' and encrypt the key with supplied passphrase 'pw'.

func (*PrivateKey) SignFile

func (sk *PrivateKey) SignFile(fn string) (*Signature, error)

Read and sign a file

We calculate the signature differently here: We first calculate the SHA-512 checksum of the file and its size. We sign the checksum.

func (*PrivateKey) SignMessage

func (sk *PrivateKey) SignMessage(ck []byte, comment string) (*Signature, error)

Sign a prehashed Message; return the signature as opaque bytes Signature is an YAML file:

Comment: source file path
Signature: Ed25519 signature

func (*PrivateKey) ToCurve25519SK

func (sk *PrivateKey) ToCurve25519SK() []byte

Convert an Ed25519 Private Key to Curve25519 Private key

func (*PrivateKey) UnmarshalBinary

func (sk *PrivateKey) UnmarshalBinary(b []byte, getpw func() ([]byte, error)) error

UnmarshalBinary unmarshals the private key and optionally invokes the caller provided getpw() function to read the password if needed. If the input byte stream 'b' is an OpenSSH ed25519 key, this function transparently decodes it.

type PublicKey

type PublicKey struct {
	Pk []byte

	// Comment string
	Comment string
	// contains filtered or unexported fields
}

Public Ed25519 key

func MakePublicKey

func MakePublicKey(yml []byte) (*PublicKey, error)

Parse a serialized public in 'yml' and return the resulting public key instance

func MakePublicKeyFromString

func MakePublicKeyFromString(s string) (*PublicKey, error)

Make a public key from a string

func ParseAuthorizedKeys

func ParseAuthorizedKeys(in []byte) ([]*PublicKey, error)

ParseAuthorizedKeys parses a public key from an authorized_keys file used in OpenSSH according to the sshd(8) manual page.

func PublicKeyFromBytes

func PublicKeyFromBytes(b []byte) (*PublicKey, error)

Make a public key from a byte string

func ReadPublicKey

func ReadPublicKey(fn string) (*PublicKey, error)

Read the public key from 'fn' and create new instance of PublicKey

func (*PublicKey) Hash

func (pk *PublicKey) Hash() []byte

Public Key Hash

func (*PublicKey) MarshalBinary

func (pk *PublicKey) MarshalBinary(comment string) ([]byte, error)

MarshalBinary marshals a PublicKey into a byte array

func (*PublicKey) Serialize

func (pk *PublicKey) Serialize(fn, comment string, ovwrite bool) error

Serialize a PublicKey into file 'fn' with a human readable 'comment'. If 'ovwrite' is true, overwrite the file if it exists.

func (*PublicKey) ToCurve25519PK

func (pk *PublicKey) ToCurve25519PK() []byte

Convert an Ed25519 Public Key to Curve25519 public key from github.com/FiloSottile/age

func (*PublicKey) UnmarshalBinary

func (pk *PublicKey) UnmarshalBinary(yml []byte) error

UnmarshalBinary constructs a PublicKey from a previously marshaled byte stream instance. In addition, it is also capable of parsing an OpenSSH ed25519 public key.

func (*PublicKey) VerifyFile

func (pk *PublicKey) VerifyFile(fn string, sig *Signature) (bool, error)

Verify a signature 'sig' for file 'fn' against public key 'pk' Return True if signature matches, False otherwise

func (*PublicKey) VerifyMessage

func (pk *PublicKey) VerifyMessage(ck []byte, sig *Signature) bool

Verify a signature 'sig' for a pre-calculated checksum 'ck' against public key 'pk' Return True if signature matches, False otherwise

type Signature

type Signature struct {
	Sig []byte // Ed25519 sig bytes
	// contains filtered or unexported fields
}

An Ed25519 Signature

func ReadSignature

func ReadSignature(fn string) (*Signature, error)

Read serialized signature from file 'fn' and construct a Signature object

func (*Signature) IsPKMatch

func (sig *Signature) IsPKMatch(pk *PublicKey) bool

IsPKMatch returns true if public key 'pk' can potentially validate the signature. It does this by comparing the hash of 'pk' against 'Pkhash' of 'sig'.

func (*Signature) MarshalBinary

func (sig *Signature) MarshalBinary(comment string) ([]byte, error)

MarshalBinary marshals a signature into a byte stream with an optional caller supplied comment.

func (*Signature) Serialize

func (sig *Signature) Serialize(fn, comment string, ovwrite bool) error

Serialize a signature suitable for storing in durable media

func (*Signature) UnmarshalBinary

func (sig *Signature) UnmarshalBinary(b []byte) error

UnmarshalBinary constructs a Signature from a previously serialized bytestream

Jump to

Keyboard shortcuts

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