forked from calccrypto/OpenPGP
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsigcalc.cpp
124 lines (106 loc) · 4.58 KB
/
sigcalc.cpp
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
#include "sigcalc.h"
std::string addtrailer(const std::string & data, const Tag2::Ptr & sig){
std::string trailer = sig -> get_up_to_hashed();
if (sig -> get_version() == 3){
return data + trailer.substr(1, trailer.size() - 1); // remove version from trailer
}
else if (sig -> get_version() == 4){
return data + trailer + "\x04\xff" + unhexlify(makehex(trailer.size(), 8));
}
else{
std::stringstream s; s << static_cast <unsigned int> (sig -> get_version());
throw std::runtime_error("Error: addtrailer for version " + s.str() + " not defined.");
}
return ""; // should never reach here; mainly just to remove compiler warnings
}
std::string overkey(const Key::Ptr & key){
std::string key_str = key -> raw();
// remove private data by copying over to Tag 6
Tag6 tag6(key_str);
key_str = tag6.raw();
return "\x99" + unhexlify(makehex(key_str.size(), 4)) + key_str;
}
std::string certification(uint8_t version, const ID::Ptr & id){
if (version == 3){
return id -> raw();
}
else if (version == 4){
std::string data = id -> raw();
if (id -> get_tag() == 13){ // User ID packet
return "\xb4" + unhexlify(makehex(data.size(), 8)) + data;
}
else if (id -> get_tag() == 17){// User Attribute packet
return "\xd1" + unhexlify(makehex(data.size(), 8)) + data;
}
}
else{
std::stringstream s; s << static_cast <unsigned int> (version);
throw std::runtime_error("Error: Certification for version " + s.str() + " not defined.");
}
return ""; // should never reach here; mainly just to remove compiler warnings
}
std::string to_sign_00(const std::string & data, const Tag2::Ptr & tag2){
return use_hash(tag2 -> get_hash(), addtrailer(data, tag2));
}
std::string to_sign_01(const std::string & data, const Tag2::Ptr & tag2){
std::string out;
// convert line endings to <CR><LF>
if (data[0] == '\n'){
out = "\r";
}
out += std::string(1, data[0]);
for(unsigned int x = 1; x < data.size(); x++){
if ((data[x] == '\n') && (data[x - 1] != '\r')){ // check to make sure lines aren't already <CR><LF>
out += "\r";
}
out += std::string(1, data[x]);
}
return use_hash(tag2 -> get_hash(), addtrailer(out, tag2));
}
std::string to_sign_02(const Tag2::Ptr & tag2){
if (tag2 -> get_version() == 3){
throw std::runtime_error("Error: It does not make sense to have a V3 standalone signature.");
}
return use_hash(tag2 -> get_hash(), addtrailer("", tag2));
}
std::string to_sign_10(const Key::Ptr & key, const ID::Ptr & id, const Tag2::Ptr & tag2){
return use_hash(tag2 -> get_hash(), addtrailer(overkey(key) + certification(tag2 -> get_version(), id), tag2));
}
std::string to_sign_11(const Key::Ptr & key, const ID::Ptr & id, const Tag2::Ptr & tag2){
return to_sign_10(key, id, tag2);
}
std::string to_sign_12(const Key::Ptr & key, const ID::Ptr & id, const Tag2::Ptr & tag2){
return to_sign_10(key, id, tag2);
}
std::string to_sign_13(const Key::Ptr & key, const ID::Ptr & id, const Tag2::Ptr & tag2){
return to_sign_10(key, id, tag2);
}
std::string to_sign_18(const Key::Ptr & primary, const Key::Ptr & key, const Tag2::Ptr & tag2){
return use_hash(tag2 -> get_hash(), addtrailer(overkey(primary) + overkey(key), tag2));
}
std::string to_sign_19(const Key::Ptr & primary, const Key::Ptr & subkey, const Tag2::Ptr & tag2){
return use_hash(tag2 -> get_hash(), addtrailer(overkey(primary) + overkey(subkey), tag2));
}
std::string to_sign_1f(const Tag2::Ptr & /*tag2*/){
throw std::runtime_error("Error: Signature directly on a key has not implemented.");
// return use_hash(tag2 -> get_hash(), addtrailer("", tag2));
return "";
}
std::string to_sign_20(const Key::Ptr & key, const Tag2::Ptr & tag2){
return use_hash(tag2 -> get_hash(), addtrailer(overkey(key), tag2));
}
std::string to_sign_28(const Key::Ptr & key, const Tag2::Ptr & tag2){
return use_hash(tag2 -> get_hash(), addtrailer(overkey(key), tag2));
}
std::string to_sign_30(const Key::Ptr & key, const ID::Ptr & id, const Tag2::Ptr & tag2){
return to_sign_10(key, id, tag2);
}
std::string to_sign_40(const Tag2::Ptr & /*tag2*/){
throw std::runtime_error("Error: Signature directly on a key has not implemented.");
// return use_hash(tag2 -> get_hash(), addtrailer("", tag2));
return "";
}
std::string to_sign_50(const Tag2 & sig, const Tag2::Ptr & /*tag2*/){
std::string data = sig.get_without_unhashed();
return "\x88" + unhexlify(makehex(data.size(), 8)) + data;
}