Repository navigation
Expand file tree
/
Copy pathPasswordFile.cpp
More file actions
118 lines (85 loc) · 2.22 KB
/
Copy pathPasswordFile.cpp
File metadata and controls
118 lines (85 loc) · 2.22 KB
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
#include "PasswordFile.h"
#include <libutils/Exceptions.h>
#include <crypto++/modes.h>
#include <crypto++/filters.h>
#include <crypto++/osrng.h>
#include <cstdio>
#include <strings.h>
#include <arpa/inet.h>
#include <fstream>
using namespace Utils;
using namespace CryptoPP;
namespace
{
constexpr uint8_t OPI_KEY_VERSION = 0x01;
using opi_key = struct _opi_key{
uint16_t version;
uint8_t iv[16];
uint16_t length;
uint8_t key[8192];
};
const uint8_t pkey[32] = {
0x91, 0x70, 0x71, 0xcd, 0xf6, 0xfd, 0xbf, 0x41,
0xf6, 0x34, 0xe4, 0x3a, 0x5a, 0xe9, 0x9d, 0x99,
0xb5, 0x79, 0xb6, 0x30, 0xab, 0x08, 0x11, 0x83,
0x58, 0xfe, 0xca, 0xbd, 0x4e, 0x71, 0x50, 0x38
};
}
string PasswordFile::Read(const string &path)
{
opi_key key;
ifstream ifs(path, ios_base::binary);
if( ! ifs )
{
throw ErrnoException("Could not read file");
}
ifs.read( (char*) &key, sizeof(opi_key) );
if( ! ifs )
{
throw ErrnoException("Failed to read password file");
}
ifs.close();
key.length = ntohs( key.length );
key.version = ntohs( key.version );
string plain;
CBC_Mode< AES >::Decryption d( pkey, sizeof(pkey), key.iv );
string source( (const char*) key.key, key.length);
StringSource s( source , true,
new StreamTransformationFilter( d,
new StringSink(plain)
)
);
return plain;
}
void PasswordFile::Write(const string& path, const string &password)
{
AutoSeededRandomPool rng;
opi_key key;
if( password.size() > sizeof(opi_key::key ) )
{
throw runtime_error("Password to long");
}
rng.GenerateBlock( (unsigned char*) &key , sizeof(opi_key));
rng.GenerateBlock( (unsigned char*) &key.iv, sizeof(opi_key::iv));
CBC_Mode< AES >::Encryption e( pkey, sizeof(pkey), key.iv );
string ciphered;
StringSource s(password, true,
new StreamTransformationFilter( e,
new StringSink(ciphered)
)
);
memcpy( key.key, ciphered.c_str(), ciphered.size() );
key.length = htons(ciphered.size());
key.version = htons(OPI_KEY_VERSION);
ofstream ofs(path, ios_base::binary | ios_base::trunc);
if( ! ofs )
{
throw ErrnoException("Failed to open password file for writing");
}
ofs.write( (char*) &key, sizeof(opi_key));
if( ! ofs )
{
throw ErrnoException("Failed to write password file");
}
ofs.close();
}