~ubuntu-branches/ubuntu/quantal/psi/quantal

« back to all changes in this revision

Viewing changes to cutestuff/xmlsec/keyops.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-04-14 18:57:30 UTC
  • mfrom: (2.1.9 hardy)
  • Revision ID: james.westby@ubuntu.com-20080414185730-528re3zp0m2hdlhi
Tags: 0.11-8
* added CONFIG -= link_prl to .pro files and removed dependencies
  which are made unnecessary by this change
* Fix segfault when closing last chat tab with qt4.4
  (This is from upstream svn, rev. 1101) (Closes: Bug#476122)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include"keyops.h"
2
 
 
3
 
#include"../util/bytestream.h"
4
 
#include"../util/base64.h"
5
 
#include"../util/sha1.h"
6
 
 
7
 
bool sym_encrypt(const QByteArray &data, const Cipher::Key &key, const QByteArray &iv, QString *out)
8
 
{
9
 
        QByteArray encData = iv.copy();
10
 
        bool ok;
11
 
        QByteArray a = Cipher::encrypt(data, key, iv, true, &ok);
12
 
        if(!ok)
13
 
                return false;
14
 
        ByteStream::appendArray(&encData, a);
15
 
 
16
 
        *out = Base64::arrayToString(encData);
17
 
        return true;
18
 
}
19
 
 
20
 
bool sym_decrypt(const QString &str, const Cipher::Key &key, QByteArray *out)
21
 
{
22
 
        QByteArray data = Base64::stringToArray(str);
23
 
        int r = Cipher::ivSize(key.type());
24
 
        if(r == -1)
25
 
                return false;
26
 
        if((int)data.size() < r)
27
 
                return false;
28
 
        QByteArray iv = ByteStream::takeArray(&data, r);
29
 
        bool ok;
30
 
        QByteArray result = Cipher::decrypt(data, key, iv, true, &ok);
31
 
        if(!ok)
32
 
                return false;
33
 
 
34
 
        *out = result;
35
 
        return true;
36
 
}
37
 
 
38
 
static QByteArray calcCMS(const QByteArray &key)
39
 
{
40
 
        QByteArray a = SHA1::hash(key);
41
 
        a.resize(8);
42
 
        return a;
43
 
}
44
 
 
45
 
unsigned char sym_3des_fixed_iv[8] = { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 };
46
 
unsigned char sym_aes_fixed_val[8] = { 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6 };
47
 
 
48
 
static QByteArray cat64(const QByteArray &a1, const QByteArray &a2)
49
 
{
50
 
        QByteArray out = a1.copy();
51
 
        ByteStream::appendArray(&out, a2);
52
 
        return out;
53
 
}
54
 
 
55
 
static QByteArray xor64(const QByteArray &a1, const QByteArray &a2)
56
 
{
57
 
        QByteArray out(a1.size());
58
 
        for(uint n = 0; n < a1.size(); ++n)
59
 
                out[n] = a1[n] ^ a2[n];
60
 
        return out;
61
 
}
62
 
 
63
 
static QByteArray msb64(const QByteArray &a)
64
 
{
65
 
        QByteArray out(8);
66
 
        for(uint n = 0; n < 8; ++n)
67
 
                out[n] = a[n];
68
 
        return out;
69
 
}
70
 
 
71
 
static QByteArray lsb64(const QByteArray &a)
72
 
{
73
 
        QByteArray out(8);
74
 
        for(uint n = 0; n < 8; ++n)
75
 
                out[n] = a[n+8];
76
 
        return out;
77
 
}
78
 
 
79
 
static QByteArray get64(const QByteArray &from, uint x)
80
 
{
81
 
        QByteArray out(8);
82
 
        int base = (x-1) * 8;
83
 
        for(uint n = 0; n < 8; ++n)
84
 
                out[n] = from[base+n];
85
 
        return out;
86
 
}
87
 
 
88
 
static void set64(QByteArray *from, uint x, const QByteArray &a)
89
 
{
90
 
        int base = (x-1) * 8;
91
 
        for(uint n = 0; n < 8; ++n)
92
 
                (*from)[base+n] = a[n];
93
 
}
94
 
 
95
 
static QByteArray uintTo64(uint x)
96
 
{
97
 
        QByteArray out(8);
98
 
        out[0] = 0x00;
99
 
        out[1] = 0x00;
100
 
        out[2] = 0x00;
101
 
        out[3] = 0x00;
102
 
        out[4] = (x >> 24) & 0xff;
103
 
        out[5] = (x >> 16) & 0xff;
104
 
        out[6] = (x >>  8) & 0xff;
105
 
        out[7] = (x >>  0) & 0xff;
106
 
        return out;
107
 
}
108
 
 
109
 
bool sym_keywrap(const QByteArray &data, const Cipher::Key &key, QString *out)
110
 
{
111
 
        int x = key.type();
112
 
        if(x == Cipher::TripleDES) {
113
 
                QByteArray cks = calcCMS(data);
114
 
                QByteArray wkcks = data.copy();
115
 
                ByteStream::appendArray(&wkcks, cks);
116
 
                QByteArray iv = Cipher::generateIV(key.type());
117
 
                bool ok;
118
 
                QByteArray temp1 = Cipher::encrypt(wkcks, key, iv, false, &ok);
119
 
                if(!ok)
120
 
                        return false;
121
 
                QByteArray temp2 = iv;
122
 
                ByteStream::appendArray(&temp2, temp1);
123
 
                QByteArray temp3(temp2.size());
124
 
                int n2 = (int)temp2.size()-1;
125
 
                for(int n = 0; n < (int)temp2.size(); ++n)
126
 
                        temp3[n2--] = temp2[n];
127
 
                memcpy(iv.data(), sym_3des_fixed_iv, 8);
128
 
                QByteArray final = Cipher::encrypt(temp3, key, iv, false, &ok);
129
 
                if(!ok)
130
 
                        return false;
131
 
 
132
 
                *out = Base64::arrayToString(final);
133
 
                return true;
134
 
        }
135
 
        else if(x == Cipher::AES_128 || x == Cipher::AES_256) {
136
 
                QByteArray c;
137
 
                QByteArray work = data.copy();
138
 
                int n = work.size() / 8;
139
 
                if(work.size() % 8)
140
 
                        return false;
141
 
                if(n < 1)
142
 
                        return false;
143
 
 
144
 
                if(n == 1) {
145
 
                        QByteArray val(8);
146
 
                        memcpy(val.data(), sym_aes_fixed_val, 8);
147
 
                        bool ok;
148
 
                        c = Cipher::encrypt(cat64(val, work), key, QByteArray(), false, &ok);
149
 
                        if(!ok)
150
 
                                return false;
151
 
                }
152
 
                else {
153
 
                        QByteArray r = work;
154
 
                        QByteArray a(8);
155
 
                        memcpy(a.data(), sym_aes_fixed_val, 8);
156
 
 
157
 
                        for(int j = 0; j <= 5; ++j) {
158
 
                                for(int i = 1; i <= n; ++i) {
159
 
                                        uint t = i + (j * n);
160
 
                                        bool ok;
161
 
                                        QByteArray b = Cipher::encrypt(cat64(a, get64(r, i)), key, QByteArray(), false, &ok);
162
 
                                        if(!ok)
163
 
                                                return false;
164
 
                                        a = xor64(uintTo64(t), msb64(b));
165
 
                                        set64(&r, i, lsb64(b));
166
 
                                }
167
 
                        }
168
 
 
169
 
                        c = a;
170
 
                        ByteStream::appendArray(&c, r);
171
 
                }
172
 
 
173
 
                *out = Base64::arrayToString(c);
174
 
                return true;
175
 
        }
176
 
 
177
 
        return false;
178
 
}
179
 
 
180
 
bool sym_keyunwrap(const QString &str, const Cipher::Key &key, QByteArray *out)
181
 
{
182
 
        int x = key.type();
183
 
        QByteArray data = Base64::stringToArray(str);
184
 
        if(x == Cipher::TripleDES) {
185
 
                QByteArray iv(8);
186
 
                memcpy(iv.data(), sym_3des_fixed_iv, 8);
187
 
                bool ok;
188
 
                QByteArray temp3 = Cipher::decrypt(data, key, iv, false, &ok);
189
 
                if(!ok)
190
 
                        return false;
191
 
                QByteArray temp2(temp3.size());
192
 
                int n2 = (int)temp3.size()-1;
193
 
                for(int n = 0; n < (int)temp3.size(); ++n)
194
 
                        temp2[n2--] = temp3[n];
195
 
                if((int)temp2.size() < 8)
196
 
                        return false;
197
 
                iv = ByteStream::takeArray(&temp2, 8);
198
 
                QByteArray temp1 = temp2;
199
 
                QByteArray wkcks = Cipher::decrypt(temp1, key, iv, false, &ok);
200
 
                if(!ok)
201
 
                        return false;
202
 
                if((int)wkcks.size() < 8)
203
 
                        return false;
204
 
                QByteArray wk = ByteStream::takeArray(&wkcks, wkcks.size() - 8);
205
 
                QByteArray cks = wkcks;
206
 
                QByteArray t = calcCMS(wk);
207
 
 
208
 
                if(cks.size() != t.size())
209
 
                        return false;
210
 
                for(int n = 0; n < (int)t.size(); ++n) {
211
 
                        if(t[n] != cks[n])
212
 
                                return false;
213
 
                }
214
 
                *out = wk;
215
 
                return true;
216
 
        }
217
 
        else if(x == Cipher::AES_128 || x == Cipher::AES_256) {
218
 
                QByteArray p;
219
 
                QByteArray work = data.copy();
220
 
                if(work.size() % 8)
221
 
                        return false;
222
 
                int n = (work.size() / 8) - 1;
223
 
                if(n < 1)
224
 
                        return false;
225
 
 
226
 
                QByteArray a;
227
 
                if(n == 1) {
228
 
                        bool ok;
229
 
                        QByteArray b = Cipher::decrypt(work, key, QByteArray(), false, &ok);
230
 
                        if(!ok)
231
 
                                return false;
232
 
                        ByteStream::appendArray(&p, lsb64(b));
233
 
                        a = msb64(b);
234
 
                }
235
 
                else {
236
 
                        a = ByteStream::takeArray(&work, 8);
237
 
                        QByteArray r = work;
238
 
                        for(int j = 5; j >= 0; --j) {
239
 
                                for(int i = n; i >= 1; --i) {
240
 
                                        uint t = i + (j * n);
241
 
                                        QByteArray ta = xor64(uintTo64(t), a);
242
 
                                        bool ok;
243
 
                                        QByteArray b = Cipher::decrypt(cat64(ta, get64(r, i)), key, QByteArray(), false, &ok);
244
 
                                        if(!ok)
245
 
                                                return false;
246
 
                                        a = msb64(b);
247
 
                                        set64(&r, i, lsb64(b));
248
 
                                }
249
 
                        }
250
 
 
251
 
                        p = r;
252
 
                }
253
 
 
254
 
                for(int i = 0; i < 8; ++i) {
255
 
                        if((unsigned char)a[i] != sym_aes_fixed_val[i])
256
 
                                return false;
257
 
                }
258
 
 
259
 
                *out = p;
260
 
                return true;
261
 
        }
262
 
 
263
 
        return false;
264
 
}