Build Status GoDoc


This package has been moved into Further contributions should be made there, this project has been archived.

Package openpgp provides OpenPGP packet processing for keyservers. It is intended to support verification of signed key material and certifications.


Public keyservers are intended to be beneficial directory service, but in the OpenPGP cryptosystem, they are not intended to be securely reliable authorities on the authenticity of keys. Rather, they are tasked with propagating key material -- good, bad or ugly -- for OpenPGP agents like GnuPG to determine authenticity and acceptable content.

This package supports the unique concerns of a keyserver, which is not (and probably should not be) addressed in a typical OpenPGP implementation oriented toward user agents.


  • Merging packets among two keyrings.
  • De-duplication or preservation of redundant packets in a public keyring.
  • Resolve revocations, expirations and certifying self-signatures for non-authoritative purposes.
  • Tolerance and classification of experimental, new, and outdated key material for interoperability.
  • Keyring digest calculation method compatible with SKS.
  • Hierarchical entity modeling of keyring packets.
  • Unique scoped identifiers for all packets.
  • Reversed-hex key IDs support prefix matching, optimal for many database indexes.


This package is newly API versioned by Expect a v1 branch once it stabilizes.

import ""


AGPLv3. Copyright (c) 2015 Casey Marshall.




This section is empty.


View Source
var ErrInvalidPacketType error = errors.New("Invalid packet type")
View Source
var ErrMissingSignature = fmt.Errorf("Key material missing an expected signature")
View Source
var ErrPacketRecordState error = errors.New("Packet record state has not been properly initialized")


func AlgorithmName

func AlgorithmName(code int) string

func CollectDuplicates

func CollectDuplicates(key *PrimaryKey) error

func DropDuplicates

func DropDuplicates(key *PrimaryKey) error

func Merge

func Merge(dst, src *PrimaryKey) error

func Reverse

func Reverse(s string) string

func SksDigest

func SksDigest(key *PrimaryKey, h hash.Hash) (string, error)

SksDigest calculates a cumulative message digest on all OpenPGP packets for a given primary public key, using the same ordering as SKS, the Synchronizing Key Server. Use MD5 for matching digest values with SKS.

func Sort

func Sort(pubkey *PrimaryKey)

Sort reorders the key material based on precedence rules.

func WriteArmoredPackets

func WriteArmoredPackets(w io.Writer, roots []*PrimaryKey) error

func WritePackets

func WritePackets(w io.Writer, key *PrimaryKey) error


type CheckSig

type CheckSig struct {
	PrimaryKey *PrimaryKey
	Signature  *Signature
	Error      error

CheckSig represents the result of checking a self-signature.

type OpaqueKeyring

type OpaqueKeyring struct {
	Packets      []*packet.OpaquePacket
	RFingerprint string
	Md5          string
	Sha256       string
	Error        error
	Position     int64

func (*OpaqueKeyring) Parse

func (ok *OpaqueKeyring) Parse() (*PrimaryKey, error)

type OpaqueKeyringChan

type OpaqueKeyringChan chan *OpaqueKeyring

func ReadOpaqueKeyrings

func ReadOpaqueKeyrings(r io.Reader) OpaqueKeyringChan

type Packet

type Packet struct {

	// UUID is a universally unique identifier string for this packet. Not
	// necessarily a standard UUID format though.
	UUID string

	// Tag indicates the OpenPGP package tag type.
	Tag uint8

	// Parsed indicates whether Hockeypuck is able to parse the contents of
	// this packet or if it is unsupported/malformed key material. Unparsed
	// content has not been signature verified, and so Hockeypuck may not have
	// been able to filter out invalid content.
	Parsed bool

	// Count indicates the number of times this packet occurs in the keyring.
	Count int

	// Packet contains the raw packet bytes.
	Packet []byte

func ParseOther

func ParseOther(op *packet.OpaquePacket, parentID string) (*Packet, error)

type PrimaryKey

type PrimaryKey struct {

	MD5    string
	SHA256 string

	SubKeys        []*SubKey
	UserIDs        []*UserID
	UserAttributes []*UserAttribute

func ParsePrimaryKey

func ParsePrimaryKey(op *packet.OpaquePacket) (*PrimaryKey, error)

func (*PrimaryKey) SelfSigs

func (pubkey *PrimaryKey) SelfSigs() *SelfSigs

type PrimaryKeyChan

type PrimaryKeyChan chan *ReadKeyResult

func MustReadArmorKeys

func MustReadArmorKeys(r io.Reader) PrimaryKeyChan

func ReadArmorKeys

func ReadArmorKeys(r io.Reader) (PrimaryKeyChan, error)

func ReadKeys

func ReadKeys(r io.Reader) PrimaryKeyChan

ReadKeys reads public key material from input and sends them on a channel. Caller must receive all keys until the channel is closed.

func (PrimaryKeyChan) MustParse

func (c PrimaryKeyChan) MustParse() []*PrimaryKey

type PublicKey

type PublicKey struct {

	RFingerprint string
	RKeyID       string
	RShortID     string

	// Creation stores the timestamp when the public key was created.
	Creation time.Time

	// Expiration stores the timestamp when the public key expires.
	Expiration time.Time

	// Algorithm stores the algorithm type of the public key.
	Algorithm int

	// BitLen stores the bit length of the public key.
	BitLen int

	Signatures []*Signature
	Others     []*Packet

func (*PublicKey) Fingerprint

func (pk *PublicKey) Fingerprint() string

func (*PublicKey) KeyID

func (pk *PublicKey) KeyID() string

func (*PublicKey) QualifiedFingerprint

func (pk *PublicKey) QualifiedFingerprint() string

func (*PublicKey) ShortID

func (pk *PublicKey) ShortID() string

type ReadKeyResult

type ReadKeyResult struct {
	Error error

type SelfSigs

type SelfSigs struct {
	Revocations    []*CheckSig
	Certifications []*CheckSig
	Expirations    []*CheckSig
	Primaries      []*CheckSig
	Errors         []*CheckSig
	// contains filtered or unexported fields

SelfSigs holds self-signatures on OpenPGP targets, which may be keys, user IDs, or user attributes.

func (*SelfSigs) ExpiresAt

func (s *SelfSigs) ExpiresAt() (time.Time, bool)

func (*SelfSigs) PrimarySince

func (s *SelfSigs) PrimarySince() (time.Time, bool)

func (*SelfSigs) RevokedSince

func (s *SelfSigs) RevokedSince() (time.Time, bool)

func (*SelfSigs) Valid

func (s *SelfSigs) Valid() bool

func (*SelfSigs) ValidSince

func (s *SelfSigs) ValidSince() (time.Time, bool)

type Signature

type Signature struct {

	SigType      int
	RIssuerKeyID string
	Creation     time.Time
	Expiration   time.Time
	Primary      bool

func ParseSignature

func ParseSignature(op *packet.OpaquePacket, pubkeyUUID, scopedUUID string) (*Signature, error)

func (*Signature) IssuerKeyID

func (sig *Signature) IssuerKeyID() string

type SubKey

type SubKey struct {

func ParseSubKey

func ParseSubKey(op *packet.OpaquePacket) (*SubKey, error)

func (*SubKey) SelfSigs

func (subkey *SubKey) SelfSigs(pubkey *PrimaryKey) *SelfSigs

type UserAttribute

type UserAttribute struct {

	Images [][]byte

	Signatures []*Signature
	Others     []*Packet

func ParseUserAttribute

func ParseUserAttribute(op *packet.OpaquePacket, parentID string) (*UserAttribute, error)

func (*UserAttribute) SelfSigs

func (uat *UserAttribute) SelfSigs(pubkey *PrimaryKey) *SelfSigs

type UserID

type UserID struct {

	Keywords string

	Signatures []*Signature
	Others     []*Packet

func ParseUserID

func ParseUserID(op *packet.OpaquePacket, parentID string) (*UserID, error)

func (*UserID) SelfSigs

func (uid *UserID) SelfSigs(pubkey *PrimaryKey) *SelfSigs


Path Synopsis