~cmars/hockeypuck/master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
   Hockeypuck - OpenPGP key server
   Copyright (C) 2012-2014  Casey Marshall

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, version 3.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package openpgp

import (
	"bytes"
	"errors"
	"io"

	"code.google.com/p/go.crypto/openpgp/packet"
)

var ErrInvalidPacketType error = errors.New("Invalid packet type")
var ErrPacketRecordState error = errors.New("Packet record state has not been properly initialized")

// PacketState indicates the validity of the public key material and special
// policies that may apply to it. The lower 16 bits are either neutral policy
// or positive validation indicators. The upper 16 bits indicate validation failure
// that the key material is either invalid, unverifiable or failed to meet some policy
// criteria.
type PacketState int

const (
	// Bits 0-15 indicate positive verification status and public key policies

	// Key material has been registered with Hockeypuck by the key owner,
	// who has signed a nonced challenge message with the associated private key.
	PacketStateRegistered = 1 << 0

	// Key material is cloaked. Hockeypuck will respond as if the key does not exist
	// unless the HKP request has proper authentication.
	PacketStateCloaked = 1 << 1

	// Signature has been checked and verified
	PacketStateSigOk = 1 << 2

	// Bits 16-23 indicate verification failure of the key material.

	// Key material is banned from HKP results unconditionally. Could be signature
	// graphiti or other unwanted content.
	PacketStateSpam = 1 << 16

	// Key material is considered to be abandoned according to keyserver policy.
	PacketStateAbandoned = 1 << 17

	// Key material lacks a valid, non-expired self-signature
	PacketStateNoSelfSig = 1 << 18

	// Subkey material lacks a valid, non-expired binding-signature
	PacketStateNoBindingSig = 1 << 19

	// Public key is unsupported (unknown algorithm code, etc.)
	PacketStateUnsuppPubkey = 1 << 20
)

type PacketVisitor func(PacketRecord) error

type PacketRecord interface {
	GetOpaquePacket() (*packet.OpaquePacket, error)
	GetPacket() (packet.Packet, error)
	Read() error
	Serialize(w io.Writer) error
	setPacket(packet.Packet) error
	Uuid() string
	Visit(PacketVisitor) error
}

type publicKeyRecord interface {
	publicKey() *packet.PublicKey
	publicKeyV3() *packet.PublicKeyV3
}

type Signable interface {
	AddSignature(*Signature)
	RemoveSignature(*Signature)
}

func toOpaquePacket(buf []byte) (*packet.OpaquePacket, error) {
	r := packet.NewOpaqueReader(bytes.NewBuffer(buf))
	return r.Next()
}

type packetSlice []*packet.OpaquePacket

func (ps packetSlice) Len() int {
	return len(ps)
}

func (ps packetSlice) Swap(i, j int) {
	ps[i], ps[j] = ps[j], ps[i]
}

type sksPacketSorter struct{ packetSlice }

func (sps sksPacketSorter) Less(i, j int) bool {
	cmp := int32(sps.packetSlice[i].Tag) - int32(sps.packetSlice[j].Tag)
	if cmp < 0 {
		return true
	} else if cmp > 0 {
		return false
	}
	return bytes.Compare(sps.packetSlice[i].Contents, sps.packetSlice[j].Contents) < 0
}