forked from calccrypto/OpenPGP
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKey.h
233 lines (194 loc) · 9.57 KB
/
Key.h
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
Key.h
OpenPGP Transferable key data structure (RFC 4880 sec 11.1 and 11.2)
Copyright (c) 2013 - 2018 Jason Lee @ calccrypto at gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef __OPENPGP_KEY__
#define __OPENPGP_KEY__
#include <algorithm>
#include <functional>
#include <set>
#include "Packets/packets.h"
#include "PKA/PKAs.h"
#include "PGP.h"
namespace OpenPGP {
class Key : public PGP {
public:
// Map between two packets
typedef std::multimap <Packet::Tag::Ptr, Packet::Tag::Ptr> SigPairs;
// struct contains mapping between packets and relative signatures
struct pkey{
Packet::Tag::Ptr key; // Primary Key
SigPairs keySigs; // Map between Primary Key and Signatures
SigPairs uids; // Map between User (include UserID and User Attributes) and Signatures
SigPairs subKeys; // Map between Subkeys and Signatures
SigPairs uid_userAtt; // Map between UserID and User Attributes
Packets uid_list; // Vector with all the userID
};
private:
// for listing keys
const std::map <uint8_t, std::string> Public_Key_Type = {
std::make_pair(Packet::SECRET_KEY, "sec"),
std::make_pair(Packet::PUBLIC_KEY, "pub"),
std::make_pair(Packet::SECRET_SUBKEY, "ssb"),
std::make_pair(Packet::PUBLIC_SUBKEY, "sub"),
};
// Extract Packet from sp pushing them in np
void flatten(SigPairs sp, Packets *np, SigPairs ua_table);
Packets get_elements_by_key(SigPairs::iterator first, SigPairs::iterator last, const Packet::Tag::Ptr &key) const;
public:
typedef std::shared_ptr <Key> Ptr;
Key();
Key(const PGP & copy);
Key(const Key & copy);
Key(const std::string & data);
Key(std::istream & stream);
~Key();
// keyid that is searched for on keyservers
std::string keyid() const;
// fingerprint of entire key (primary key packet)
std::string fingerprint() const;
// version of entire key (primary key packet)
uint8_t version() const;
// output style inspired by gpg and SKS Keyserver/pgp.mit.edu
std::string list_keys(const std::size_t indents = 0, const std::size_t indent_size = 4) const;
// whether or not PGP data matches a Key format without constructing a new object
static bool meaningful(const PGP & pgp);
// whether or not *this data matches a Key format
virtual bool meaningful() const;
// return the pkey format of the key
pkey get_pkey() const;
// Merge function ported from sks keyserver ocaml code
void merge(const Key::Ptr &k);
virtual PGP::Ptr clone() const;
};
std::ostream & operator <<(std::ostream & stream, const Key & pgp);
// 11.1. Transferable Public Keys
//
// OpenPGP users may transfer public keys. The essential elements of a
// transferable public key are as follows:
//
// - One Public-Key packet
//
// - Zero or more revocation signatures
//
// - One or more User ID packets
//
// - After each User ID packet, zero or more Signature packets (certifications)
//
// - Zero or more User Attribute packets
//
// - After each User Attribute packet, zero or more Signature packets (certifications)
//
// - Zero or more Subkey packets
//
// - After each Subkey packet, one Signature packet, plus optionally a revocation
//
// The Public-Key packet occurs first. Each of the following User ID
// packets provides the identity of the owner of this public key. If
// there are multiple User ID packets, this corresponds to multiple
// means of identifying the same unique individual user; for example, a
// user may have more than one email address, and construct a User ID
// for each one.
//
// Immediately following each User ID packet, there are zero or more
// Signature packets. Each Signature packet is calculated on the
// immediately preceding User ID packet and the initial Public-Key
// packet. The signature serves to certify the corresponding public key
// and User ID. In effect, the signer is testifying to his or her
// belief that this public key belongs to the user identified by this
// User ID.
//
// Within the same section as the User ID packets, there are zero or
// more User Attribute packets. Like the User ID packets, a User
// Attribute packet is followed by zero or more Signature packets
// calculated on the immediately preceding User Attribute packet and the
// initial Public-Key packet.
//
// User Attribute packets and User ID packets may be freely intermixed
// in this section, so long as the signatures that follow them are
// maintained on the proper User Attribute or User ID packet.
// After the User ID packet or Attribute packet, there may be zero or
// more Subkey packets. In general, subkeys are provided in cases where
// the top-level public key is a signature-only key. However, any V4
// key may have subkeys, and the subkeys may be encryption-only keys,
// signature-only keys, or general-purpose keys. V3 keys MUST NOT have
// subkeys.
//
// Each Subkey packet MUST be followed by one Signature packet, which
// should be a subkey binding signature issued by the top-level key.
// For subkeys that can issue signatures, the subkey binding signature
// MUST contain an Embedded Signature subpacket with a primary key
// binding signature (0x19) issued by the subkey on the top-level key.
// Subkey and Key packets may each be followed by a revocation Signature
// packet to indicate that the key is revoked. Revocation signatures
// are only accepted if they are issued by the key itself, or by a key
// that is authorized to issue revocations via a Revocation Key
// subpacket in a self-signature by the top-level key.
//
// Transferable public-key packet sequences may be concatenated to allow
// transferring multiple public keys in one operation.
class SecretKey;
class PublicKey : public Key {
public:
typedef std::shared_ptr <PublicKey> Ptr;
PublicKey();
PublicKey(const Key & copy);
PublicKey(const PublicKey & copy);
PublicKey(const std::string & data);
PublicKey(std::istream & stream);
PublicKey(const SecretKey & sec);
~PublicKey();
// whether or not data matches the Public Key format
bool meaningful() const;
PublicKey & operator=(const PublicKey & pub);
PublicKey & operator=(const SecretKey & pri);
PGP::Ptr clone() const;
};
std::ostream & operator <<(std::ostream & stream, const PublicKey & pgp);
// 11.2. Transferable Secret Keys
//
// OpenPGP users may transfer secret keys. The format of a transferable
// secret key is the same as a transferable public key except that
// secret-key and secret-subkey packets are used instead of the public
// key and public-subkey packets. Implementations SHOULD include self-
// signatures on any user IDs and subkeys, as this allows for a complete
// public key to be automatically extracted from the transferable secret
// key. Implementations MAY choose to omit the self-signatures,
// especially if a transferable public key accompanies the transferable
// secret key.
class SecretKey : public Key {
public:
typedef std::shared_ptr <SecretKey> Ptr;
SecretKey();
SecretKey(const Key & copy);
SecretKey(const SecretKey & copy);
SecretKey(const std::string & data);
SecretKey(std::istream & stream);
~SecretKey();
// Extract Public Key data from a Secret Key
PublicKey get_public() const;
// whether or not data matches Secret Key format
bool meaningful() const;
PGP::Ptr clone() const;
};
std::ostream & operator <<(std::ostream & stream, const SecretKey & pgp);
// Search PGP keys for signing keys
Packet::Key::Ptr find_signing_key(const Key & key);
}
#endif