-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrypto.hpp
143 lines (121 loc) · 4.33 KB
/
crypto.hpp
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
#ifndef CRYPTO_HPP
#define CRYPTO_HPP
#include <string>
#include <cmath>
//Moving these to a seperate namespace for minimal global namespace cluttering does not work with clang++
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
namespace SimpleWeb {
//type must support size(), resize() and operator[]
namespace Crypto {
namespace Base64 {
template<class type>
void encode(const type& ascii, type& base64) {
BIO *bio, *b64;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bio = BIO_new(BIO_s_mem());
BIO_push(b64, bio);
BIO_get_mem_ptr(b64, &bptr);
//Write directly to base64-buffer to avoid copy
int base64_length=round(4*ceil((double)ascii.size()/3.0));
base64.resize(base64_length);
bptr->length=0;
bptr->max=base64_length+1;
bptr->data=(char*)&base64[0];
BIO_write(b64, &ascii[0], ascii.size());
BIO_flush(b64);
//To keep &base64[0] through BIO_free_all(b64)
bptr->length=0;
bptr->max=0;
bptr->data=nullptr;
BIO_free_all(b64);
}
template<class type>
type encode(const type& ascii) {
type base64;
encode(ascii, base64);
return base64;
}
template<class type>
void decode(const type& base64, type& ascii) {
//Resize ascii, however, the size is a up to two bytes too large.
ascii.resize((6*base64.size())/8);
BIO *b64, *bio;
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bio = BIO_new_mem_buf((char*)&base64[0], base64.size());
bio = BIO_push(b64, bio);
int decoded_length = BIO_read(bio, &ascii[0], ascii.size());
ascii.resize(decoded_length);
BIO_free_all(b64);
}
template<class type>
type decode(const type& base64) {
type ascii;
decode(base64, ascii);
return ascii;
}
}
template<class type>
void MD5(const type& input, type& hash) {
MD5_CTX context;
MD5_Init(&context);
MD5_Update(&context, &input[0], input.size());
hash.resize(128/8);
MD5_Final((unsigned char*)&hash[0], &context);
}
template<class type>
type MD5(const type& input) {
type hash;
MD5(input, hash);
return hash;
}
template<class type>
void SHA1(const type& input, type& hash) {
SHA_CTX context;
SHA1_Init(&context);
SHA1_Update(&context, &input[0], input.size());
hash.resize(160/8);
SHA1_Final((unsigned char*)&hash[0], &context);
}
template<class type>
type SHA1(const type& input) {
type hash;
SHA1(input, hash);
return hash;
}
template<class type>
void SHA256(const type& input, type& hash) {
SHA256_CTX context;
SHA256_Init(&context);
SHA256_Update(&context, &input[0], input.size());
hash.resize(256/8);
SHA256_Final((unsigned char*)&hash[0], &context);
}
template<class type>
type SHA256(const type& input) {
type hash;
SHA256(input, hash);
return hash;
}
template<class type>
void SHA512(const type& input, type& hash) {
SHA512_CTX context;
SHA512_Init(&context);
SHA512_Update(&context, &input[0], input.size());
hash.resize(512/8);
SHA512_Final((unsigned char*)&hash[0], &context);
}
template<class type>
type SHA512(const type& input) {
type hash;
SHA512(input, hash);
return hash;
}
}
}
#endif /* CRYPTO_HPP */