signed

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2022 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Sign

func Sign(hdr Header, body []byte, signer crypto.Signer,
	associatedData ...[]byte) (*cryptopb.SignedMessage, error)

Sign creates a signed message. The associated data is not included in the header or body.

Example (Basic)
package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"
	"time"

	"github.com/scionproto/scion/go/lib/scrypto/signed"
)

func main() {
	// Choose private key.
	privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
	if err != nil {
		panic(err)
	}

	// Define message to sign.
	hdr := signed.Header{
		SignatureAlgorithm: signed.ECDSAWithSHA512,
		Timestamp:          time.Now(),
	}
	body := []byte("very important message")

	// Sign the message.
	signedMsg, err := signed.Sign(hdr, body, privateKey)
	if err != nil {
		panic(err)
	}

	// Extract body without verification. Usually, you will not need this operation.
	unverifiedBody, err := signed.ExtractUnverifiedBody(signedMsg)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(unverifiedBody))
}
Output:

very important message
Example (WithAssociatedData)
package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"

	"github.com/scionproto/scion/go/lib/scrypto/signed"
)

func main() {
	// Choose private key.
	privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
	if err != nil {
		panic(err)
	}

	// Define message to sign.
	hdr := signed.Header{
		SignatureAlgorithm:   signed.ECDSAWithSHA512,
		AssociatedDataLength: 8,
	}
	body := []byte("very important message")
	associatedData := [][]byte{[]byte("more"), []byte("data")}

	// Sign the message.
	signedMsg, err := signed.Sign(hdr, body, privateKey, associatedData...)
	if err != nil {
		panic(err)
	}

	// Extract body without verification. Usually, you will not need this operation.
	unverifiedBody, err := signed.ExtractUnverifiedBody(signedMsg)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(unverifiedBody))
}
Output:

very important message

Types

type Header struct {
	// SignatureAlgorithm indicates the signature algorithm.
	SignatureAlgorithm SignatureAlgorithm
	// VerificationKeyID is the optional identifier for the verification key.
	VerificationKeyID []byte
	// Timestamp is the optional signature creation time.
	Timestamp time.Time
	// Metadata is optional arbitrary data that is covered by the signature.
	Metadata []byte
	// AssociatedDataLength is the length of associated data that is covered
	// by the signature, but is not included in the header and body.
	AssociatedDataLength int
}

Header represents the signed message header.

type Message

type Message struct {
	Header Header
	Body   []byte
}

Message represents the signed message.

func Verify

func Verify(signed *cryptopb.SignedMessage, key crypto.PublicKey,
	associatedData ...[]byte) (*Message, error)

Verify verifies the signed message.

Example (Basic)
package main

import (
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"

	"github.com/scionproto/scion/go/lib/scrypto/signed"
	cryptopb "github.com/scionproto/scion/go/pkg/proto/crypto"
)

func main() {
	signedMsg, publicKey := basicSignedMessage()

	verifiedMsg, err := signed.Verify(signedMsg, publicKey)
	if err != nil {
		panic(err)
	}
	meta := verifiedMsg.Header.Metadata
	keyID := verifiedMsg.Header.VerificationKeyID
	body := verifiedMsg.Body

	fmt.Printf("meta: %q keyID: %q body: %q", meta, keyID, body)
}

func basicSignedMessage() (*cryptopb.SignedMessage, crypto.PublicKey) {
	privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
	if err != nil {
		panic(err)
	}
	hdr := signed.Header{
		SignatureAlgorithm: signed.ECDSAWithSHA512,
		Metadata:           []byte("metadata"),
		VerificationKeyID:  []byte("keyID"),
	}
	body := []byte("very important message")
	signedMsg, err := signed.Sign(hdr, body, privateKey)
	if err != nil {
		panic(err)
	}
	return signedMsg, privateKey.Public()
}
Output:

meta: "metadata" keyID: "keyID" body: "very important message"
Example (WithAssociatedData)
package main

import (
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"

	"github.com/scionproto/scion/go/lib/scrypto/signed"
	cryptopb "github.com/scionproto/scion/go/pkg/proto/crypto"
)

func main() {
	signedMsg, publicKey := signedMessageWithAssociatedData()

	_, err := signed.Verify(signedMsg, publicKey)
	if err == nil {
		panic("associated data is required")
	}

	verifiedMsg, err := signed.Verify(signedMsg, publicKey, []byte("out-of-band"))
	if err != nil {
		panic(err)
	}
	meta := verifiedMsg.Header.Metadata
	keyID := verifiedMsg.Header.VerificationKeyID
	body := verifiedMsg.Body

	fmt.Printf("meta: %q keyID: %q body: %q", meta, keyID, body)
}

func signedMessageWithAssociatedData() (*cryptopb.SignedMessage, crypto.PublicKey) {
	privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
	if err != nil {
		panic(err)
	}
	hdr := signed.Header{
		SignatureAlgorithm:   signed.ECDSAWithSHA512,
		Metadata:             []byte("metadata"),
		VerificationKeyID:    []byte("keyID"),
		AssociatedDataLength: 11,
	}
	body := []byte("very important message")
	associatedData := []byte("out-of-band")
	signedMsg, err := signed.Sign(hdr, body, privateKey, associatedData)
	if err != nil {
		panic(err)
	}
	return signedMsg, privateKey.Public()
}
Output:

meta: "metadata" keyID: "keyID" body: "very important message"

type SignatureAlgorithm

type SignatureAlgorithm int
const (
	UnknownSignatureAlgorithm SignatureAlgorithm = iota
	ECDSAWithSHA256
	ECDSAWithSHA384
	ECDSAWithSHA512
)

List of supported signature algorithms

func SelectSignatureAlgorithm

func SelectSignatureAlgorithm(pub crypto.PublicKey) (SignatureAlgorithm, error)

SelectSignatureAlgorithm selects the signature algorithm based on the public key algorithm.

func (SignatureAlgorithm) String added in v0.7.0

func (a SignatureAlgorithm) String() string

type UnverifiedBody

type UnverifiedBody []byte

UnverifiedBody represents the body that was extracted without verification. The contents should not be trusted.

func ExtractUnverifiedBody

func ExtractUnverifiedBody(signed *cryptopb.SignedMessage) (UnverifiedBody, error)

ExtractUnverifiedBody extracts the body from the signed message without verification. The caller should not trust the contents.

type UnverifiedHeader

type UnverifiedHeader Header

UnverifiedHeader represents the header that was extracted without verification. The contents of this type should not be trusted.

func ExtractUnverifiedHeader

func ExtractUnverifiedHeader(signed *cryptopb.SignedMessage) (*UnverifiedHeader, error)

ExtractUnverifiedHeader extracts the header from the signed message without verification. The caller can use it to identify the appropriate key for verification.

Jump to

Keyboard shortcuts

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