krypt-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/ext/krypt/core/Makefile +221 -0
- data/ext/krypt/core/binyo-error.h +40 -0
- data/ext/krypt/core/binyo-io-buffer.h +54 -0
- data/ext/krypt/core/binyo-io.h +131 -0
- data/ext/krypt/core/extconf.h +8 -0
- data/ext/krypt/core/extconf.rb +80 -0
- data/ext/krypt/core/krypt-core.c +110 -0
- data/ext/krypt/core/krypt-core.h +97 -0
- data/ext/krypt/core/krypt-core.o +0 -0
- data/ext/krypt/core/krypt-provider.h +86 -0
- data/ext/krypt/core/krypt_asn1-internal.c +681 -0
- data/ext/krypt/core/krypt_asn1-internal.h +117 -0
- data/ext/krypt/core/krypt_asn1-internal.o +0 -0
- data/ext/krypt/core/krypt_asn1.c +2109 -0
- data/ext/krypt/core/krypt_asn1.h +88 -0
- data/ext/krypt/core/krypt_asn1.o +0 -0
- data/ext/krypt/core/krypt_asn1_codec.c +973 -0
- data/ext/krypt/core/krypt_asn1_codec.o +0 -0
- data/ext/krypt/core/krypt_asn1_in_adapter.c +178 -0
- data/ext/krypt/core/krypt_asn1_in_adapter.o +0 -0
- data/ext/krypt/core/krypt_asn1_in_chunked.c +292 -0
- data/ext/krypt/core/krypt_asn1_in_chunked.o +0 -0
- data/ext/krypt/core/krypt_asn1_in_definite.c +156 -0
- data/ext/krypt/core/krypt_asn1_in_definite.o +0 -0
- data/ext/krypt/core/krypt_asn1_parser.c +592 -0
- data/ext/krypt/core/krypt_asn1_parser.o +0 -0
- data/ext/krypt/core/krypt_asn1_template-internal.h +185 -0
- data/ext/krypt/core/krypt_asn1_template.c +459 -0
- data/ext/krypt/core/krypt_asn1_template.h +56 -0
- data/ext/krypt/core/krypt_asn1_template.o +0 -0
- data/ext/krypt/core/krypt_asn1_template_encoder.c +76 -0
- data/ext/krypt/core/krypt_asn1_template_encoder.o +0 -0
- data/ext/krypt/core/krypt_asn1_template_parser.c +1176 -0
- data/ext/krypt/core/krypt_asn1_template_parser.o +0 -0
- data/ext/krypt/core/krypt_b64-internal.h +38 -0
- data/ext/krypt/core/krypt_b64.c +391 -0
- data/ext/krypt/core/krypt_b64.h +41 -0
- data/ext/krypt/core/krypt_b64.o +0 -0
- data/ext/krypt/core/krypt_digest.c +391 -0
- data/ext/krypt/core/krypt_digest.h +51 -0
- data/ext/krypt/core/krypt_digest.o +0 -0
- data/ext/krypt/core/krypt_error.c +221 -0
- data/ext/krypt/core/krypt_error.h +46 -0
- data/ext/krypt/core/krypt_error.o +0 -0
- data/ext/krypt/core/krypt_hex-internal.h +36 -0
- data/ext/krypt/core/krypt_hex.c +255 -0
- data/ext/krypt/core/krypt_hex.h +41 -0
- data/ext/krypt/core/krypt_hex.o +0 -0
- data/ext/krypt/core/krypt_io.c +65 -0
- data/ext/krypt/core/krypt_io.h +56 -0
- data/ext/krypt/core/krypt_io.o +0 -0
- data/ext/krypt/core/krypt_io_in_pem.c +397 -0
- data/ext/krypt/core/krypt_io_in_pem.o +0 -0
- data/ext/krypt/core/krypt_missing.c +238 -0
- data/ext/krypt/core/krypt_missing.h +62 -0
- data/ext/krypt/core/krypt_missing.o +0 -0
- data/ext/krypt/core/krypt_pem.c +171 -0
- data/ext/krypt/core/krypt_pem.o +0 -0
- data/ext/krypt/core/krypt_provider-internal.h +40 -0
- data/ext/krypt/core/krypt_provider.c +136 -0
- data/ext/krypt/core/krypt_provider.o +0 -0
- data/ext/krypt/core/kryptcore.so +0 -0
- data/ext/krypt/core/mkmf.log +130 -0
- data/lib/krypt-core/version.rb +3 -0
- data/lib/krypt-core.rb +35 -0
- data/lib/kryptcore.so +0 -0
- data/spec/README +2 -0
- data/test/README +2 -0
- data/test/res/certificate.cer +0 -0
- data/test/resources.rb +48 -0
- data/test/scratch.rb +17 -0
- metadata +150 -0
@@ -0,0 +1,397 @@
|
|
1
|
+
/*
|
2
|
+
* krypt-core API - C implementation
|
3
|
+
*
|
4
|
+
* Copyright (c) 2011-2013
|
5
|
+
* Hiroshi Nakamura <nahi@ruby-lang.org>
|
6
|
+
* Martin Bosslet <martin.bosslet@gmail.com>
|
7
|
+
* All rights reserved.
|
8
|
+
*
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
10
|
+
* a copy of this software and associated documentation files (the
|
11
|
+
* "Software"), to deal in the Software without restriction, including
|
12
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
13
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
14
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
15
|
+
* the following conditions:
|
16
|
+
*
|
17
|
+
* The above copyright notice and this permission notice shall be
|
18
|
+
* included in all copies or substantial portions of the Software.
|
19
|
+
*
|
20
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
21
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
23
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
24
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
25
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
26
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
|
+
*/
|
28
|
+
|
29
|
+
#include "krypt-core.h"
|
30
|
+
|
31
|
+
enum krypt_pem_state {
|
32
|
+
HEADER = 0,
|
33
|
+
CONTENT,
|
34
|
+
FOOTER,
|
35
|
+
DONE
|
36
|
+
};
|
37
|
+
|
38
|
+
#define KRYPT_LINE_BUF_SIZE 256
|
39
|
+
|
40
|
+
typedef struct krypt_pem_parse_ctx_st {
|
41
|
+
char *line;
|
42
|
+
size_t len;
|
43
|
+
size_t off;
|
44
|
+
char *name;
|
45
|
+
} krypt_pem_parse_ctx;
|
46
|
+
|
47
|
+
typedef struct krypt_b64_buffer_st {
|
48
|
+
binyo_instream *inner;
|
49
|
+
uint8_t *buffer;
|
50
|
+
size_t len;
|
51
|
+
size_t off;
|
52
|
+
enum krypt_pem_state state;
|
53
|
+
char *name;
|
54
|
+
int eof;
|
55
|
+
} krypt_b64_buffer;
|
56
|
+
|
57
|
+
typedef struct krypt_instream_pem_st {
|
58
|
+
binyo_instream_interface *methods;
|
59
|
+
krypt_b64_buffer *buffer;
|
60
|
+
} krypt_instream_pem;
|
61
|
+
|
62
|
+
#define int_safe_cast(out, in) binyo_safe_cast_instream((out), (in), KRYPT_INSTREAM_TYPE_PEM, krypt_instream_pem)
|
63
|
+
|
64
|
+
static krypt_instream_pem* int_pem_alloc(void);
|
65
|
+
static ssize_t int_pem_read(binyo_instream *in, uint8_t *buf, size_t len);
|
66
|
+
static int int_pem_seek(binyo_instream *in, off_t offset, int whence);
|
67
|
+
static void int_pem_mark(binyo_instream *in);
|
68
|
+
static void int_pem_free(binyo_instream *in);
|
69
|
+
|
70
|
+
static binyo_instream_interface interface_pem = {
|
71
|
+
KRYPT_INSTREAM_TYPE_PEM,
|
72
|
+
int_pem_read,
|
73
|
+
NULL,
|
74
|
+
NULL,
|
75
|
+
int_pem_seek,
|
76
|
+
int_pem_mark,
|
77
|
+
int_pem_free
|
78
|
+
};
|
79
|
+
|
80
|
+
static krypt_b64_buffer*
|
81
|
+
int_krypt_b64_buffer_new(binyo_instream *original)
|
82
|
+
{
|
83
|
+
krypt_b64_buffer *ret;
|
84
|
+
ret = ALLOC(krypt_b64_buffer);
|
85
|
+
memset(ret, 0, sizeof(krypt_b64_buffer));
|
86
|
+
ret->inner = original;
|
87
|
+
ret->state = HEADER;
|
88
|
+
return ret;
|
89
|
+
}
|
90
|
+
|
91
|
+
binyo_instream *
|
92
|
+
krypt_instream_new_pem(binyo_instream *original)
|
93
|
+
{
|
94
|
+
krypt_instream_pem *in;
|
95
|
+
|
96
|
+
in = int_pem_alloc();
|
97
|
+
in->buffer = int_krypt_b64_buffer_new(original);
|
98
|
+
return (binyo_instream *) in;
|
99
|
+
}
|
100
|
+
|
101
|
+
static krypt_instream_pem*
|
102
|
+
int_pem_alloc(void)
|
103
|
+
{
|
104
|
+
krypt_instream_pem *ret;
|
105
|
+
ret = ALLOC(krypt_instream_pem);
|
106
|
+
memset(ret, 0, sizeof(krypt_instream_pem));
|
107
|
+
ret->methods = &interface_pem;
|
108
|
+
return ret;
|
109
|
+
}
|
110
|
+
|
111
|
+
static int
|
112
|
+
int_pem_seek(binyo_instream *instream, off_t offset, int whence)
|
113
|
+
{
|
114
|
+
/* TODO */
|
115
|
+
return BINYO_OK;
|
116
|
+
}
|
117
|
+
|
118
|
+
static void
|
119
|
+
int_pem_mark(binyo_instream *instream)
|
120
|
+
{
|
121
|
+
krypt_instream_pem *in;
|
122
|
+
|
123
|
+
if (!instream) return;
|
124
|
+
int_safe_cast(in, instream);
|
125
|
+
binyo_instream_mark(in->buffer->inner);
|
126
|
+
}
|
127
|
+
|
128
|
+
static void
|
129
|
+
int_pem_free_inner(krypt_instream_pem *in)
|
130
|
+
{
|
131
|
+
krypt_b64_buffer *b64;
|
132
|
+
|
133
|
+
b64 = in->buffer;
|
134
|
+
if (b64->buffer)
|
135
|
+
xfree(b64->buffer);
|
136
|
+
if (b64->name)
|
137
|
+
xfree(b64->name);
|
138
|
+
xfree(b64);
|
139
|
+
}
|
140
|
+
|
141
|
+
static void
|
142
|
+
int_pem_free(binyo_instream *instream)
|
143
|
+
{
|
144
|
+
krypt_instream_pem *in;
|
145
|
+
krypt_b64_buffer *b64;
|
146
|
+
|
147
|
+
if (!instream) return;
|
148
|
+
int_safe_cast(in, instream);
|
149
|
+
b64 = in->buffer;
|
150
|
+
|
151
|
+
binyo_instream_free(b64->inner);
|
152
|
+
int_pem_free_inner(in);
|
153
|
+
}
|
154
|
+
|
155
|
+
void
|
156
|
+
krypt_instream_pem_free_wrapper(binyo_instream *instream)
|
157
|
+
{
|
158
|
+
krypt_instream_pem *in;
|
159
|
+
|
160
|
+
if (!instream) return;
|
161
|
+
int_safe_cast(in, instream);
|
162
|
+
|
163
|
+
int_pem_free_inner(in);
|
164
|
+
xfree(in);
|
165
|
+
}
|
166
|
+
|
167
|
+
int
|
168
|
+
krypt_pem_get_last_name(binyo_instream *instream, uint8_t **out, size_t *outlen)
|
169
|
+
{
|
170
|
+
krypt_instream_pem *in;
|
171
|
+
krypt_b64_buffer *b64;
|
172
|
+
size_t retlen;
|
173
|
+
|
174
|
+
if (!instream) {
|
175
|
+
*out = NULL;
|
176
|
+
return BINYO_ERR;
|
177
|
+
}
|
178
|
+
|
179
|
+
int_safe_cast(in, instream);
|
180
|
+
b64 = in->buffer;
|
181
|
+
|
182
|
+
if (!b64->name) {
|
183
|
+
*out = NULL;
|
184
|
+
return BINYO_ERR;
|
185
|
+
}
|
186
|
+
|
187
|
+
retlen = strlen(b64->name);
|
188
|
+
*out = ALLOC_N(uint8_t, retlen);
|
189
|
+
memcpy(*out, b64->name, retlen);
|
190
|
+
*outlen = retlen;
|
191
|
+
return BINYO_OK;
|
192
|
+
}
|
193
|
+
|
194
|
+
|
195
|
+
void
|
196
|
+
krypt_pem_continue_stream(binyo_instream *instream)
|
197
|
+
{
|
198
|
+
krypt_instream_pem *in;
|
199
|
+
krypt_b64_buffer *b64;
|
200
|
+
|
201
|
+
if (!instream) return;
|
202
|
+
int_safe_cast(in, instream);
|
203
|
+
b64 = in->buffer;
|
204
|
+
b64->state = HEADER;
|
205
|
+
b64->eof = 0;
|
206
|
+
b64->off = 0;
|
207
|
+
b64->len = 0;
|
208
|
+
if (b64->name)
|
209
|
+
xfree(b64->name);
|
210
|
+
b64->name = NULL;
|
211
|
+
if (b64->buffer)
|
212
|
+
xfree(b64->buffer);
|
213
|
+
b64->buffer = NULL;
|
214
|
+
}
|
215
|
+
|
216
|
+
|
217
|
+
static int
|
218
|
+
int_match_header(krypt_pem_parse_ctx *ctx)
|
219
|
+
{
|
220
|
+
if (ctx->len == KRYPT_LINE_BUF_SIZE)
|
221
|
+
return BINYO_ERR;
|
222
|
+
if (strncmp(ctx->line, "-----BEGIN ", 11) == 0) {
|
223
|
+
size_t len;
|
224
|
+
len = ctx->len;
|
225
|
+
if (strncmp(ctx->line + len - 5, "-----", 5) != 0)
|
226
|
+
return BINYO_ERR;
|
227
|
+
ctx->name = ALLOC_N(char, len - 11 - 4);
|
228
|
+
memcpy(ctx->name, ctx->line + 11, len - 11 - 5);
|
229
|
+
ctx->name[len - 11 - 5] = '\0';
|
230
|
+
return BINYO_OK;
|
231
|
+
}
|
232
|
+
return BINYO_ERR;
|
233
|
+
}
|
234
|
+
|
235
|
+
static int
|
236
|
+
int_match_footer(krypt_pem_parse_ctx *ctx)
|
237
|
+
{
|
238
|
+
char *name = ctx->name;
|
239
|
+
|
240
|
+
if (ctx->len == KRYPT_LINE_BUF_SIZE)
|
241
|
+
return BINYO_ERR;
|
242
|
+
if (strncmp(ctx->line, "-----END ", 9) == 0) {
|
243
|
+
size_t len;
|
244
|
+
len = ctx->len;
|
245
|
+
if (strncmp(ctx->line + len - 5, "-----", 5) != 0)
|
246
|
+
return BINYO_ERR;
|
247
|
+
if (strncmp(ctx->line + 9, name, len - 9 - 5) == 0)
|
248
|
+
return BINYO_OK;
|
249
|
+
}
|
250
|
+
return BINYO_ERR;
|
251
|
+
}
|
252
|
+
|
253
|
+
static int
|
254
|
+
int_b64_fill(krypt_b64_buffer *in)
|
255
|
+
{
|
256
|
+
binyo_outstream *out;
|
257
|
+
size_t total = 0;
|
258
|
+
ssize_t linelen;
|
259
|
+
char linebuf[KRYPT_LINE_BUF_SIZE];
|
260
|
+
|
261
|
+
if (in->buffer) {
|
262
|
+
xfree(in->buffer);
|
263
|
+
in->buffer = NULL;
|
264
|
+
}
|
265
|
+
|
266
|
+
out = binyo_outstream_new_bytes_size(BINYO_IO_BUF_SIZE + KRYPT_LINE_BUF_SIZE);
|
267
|
+
linelen = binyo_instream_gets(in->inner, linebuf, KRYPT_LINE_BUF_SIZE);
|
268
|
+
|
269
|
+
while (in->state != DONE && total < BINYO_IO_BUF_SIZE && linelen != BINYO_IO_EOF) {
|
270
|
+
if (linelen == BINYO_ERR) return BINYO_ERR;
|
271
|
+
|
272
|
+
if (linelen == 0) {
|
273
|
+
linelen = binyo_instream_gets(in->inner, linebuf, KRYPT_LINE_BUF_SIZE);
|
274
|
+
continue;
|
275
|
+
}
|
276
|
+
|
277
|
+
switch (in->state) {
|
278
|
+
case HEADER:
|
279
|
+
if (linebuf[0] == '-') {
|
280
|
+
krypt_pem_parse_ctx linectx;
|
281
|
+
linectx.line = linebuf;
|
282
|
+
linectx.len = linelen;
|
283
|
+
linectx.off = 0;
|
284
|
+
if (int_match_header(&linectx) == BINYO_OK) {
|
285
|
+
in->name = linectx.name;
|
286
|
+
in->state = CONTENT;
|
287
|
+
}
|
288
|
+
}
|
289
|
+
linelen = binyo_instream_gets(in->inner, linebuf, KRYPT_LINE_BUF_SIZE);
|
290
|
+
break;
|
291
|
+
case CONTENT:
|
292
|
+
if (linebuf[0] == '-') {
|
293
|
+
in->state = FOOTER;
|
294
|
+
}
|
295
|
+
else {
|
296
|
+
if (krypt_base64_buffer_decode_to(out, (uint8_t *) linebuf, 0, linelen) == KRYPT_ERR) {
|
297
|
+
krypt_error_add("Could not decode Base64 data");
|
298
|
+
return BINYO_ERR;
|
299
|
+
}
|
300
|
+
total += linelen;
|
301
|
+
if (total < BINYO_IO_BUF_SIZE)
|
302
|
+
linelen = binyo_instream_gets(in->inner, linebuf, KRYPT_LINE_BUF_SIZE);
|
303
|
+
}
|
304
|
+
break;
|
305
|
+
case FOOTER:
|
306
|
+
if (linebuf[0] == '-') {
|
307
|
+
krypt_pem_parse_ctx linectx;
|
308
|
+
linectx.line = linebuf;
|
309
|
+
linectx.len = linelen;
|
310
|
+
linectx.off = 0;
|
311
|
+
linectx.name = in->name;
|
312
|
+
if (int_match_footer(&linectx) == BINYO_OK)
|
313
|
+
in->state = DONE;
|
314
|
+
else
|
315
|
+
linelen = binyo_instream_gets(in->inner, linebuf, KRYPT_LINE_BUF_SIZE);
|
316
|
+
}
|
317
|
+
else {
|
318
|
+
linelen = binyo_instream_gets(in->inner, linebuf, KRYPT_LINE_BUF_SIZE);
|
319
|
+
}
|
320
|
+
break;
|
321
|
+
default:
|
322
|
+
break;
|
323
|
+
}
|
324
|
+
}
|
325
|
+
|
326
|
+
if (linelen == BINYO_ERR) return BINYO_ERR;
|
327
|
+
|
328
|
+
if (in->state == DONE || linelen == BINYO_IO_EOF)
|
329
|
+
in->eof = 1;
|
330
|
+
|
331
|
+
if (linelen == BINYO_IO_EOF && in->state != DONE) {
|
332
|
+
binyo_outstream_free(out);
|
333
|
+
switch (in->state) {
|
334
|
+
case HEADER:
|
335
|
+
in->len = in->off = 0;
|
336
|
+
in->eof = 1;
|
337
|
+
return BINYO_OK;
|
338
|
+
case CONTENT:
|
339
|
+
krypt_error_add("PEM data ended prematurely");
|
340
|
+
return BINYO_ERR;
|
341
|
+
default:
|
342
|
+
krypt_error_add("Could not find matching PEM footer");
|
343
|
+
return BINYO_ERR;
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
in->off = 0;
|
348
|
+
in->len = binyo_outstream_bytes_get_bytes_free(out, &in->buffer);
|
349
|
+
return BINYO_OK;
|
350
|
+
}
|
351
|
+
|
352
|
+
static size_t
|
353
|
+
int_consume_bytes(krypt_b64_buffer *in, uint8_t *buf, size_t len)
|
354
|
+
{
|
355
|
+
size_t available, toread;
|
356
|
+
|
357
|
+
if (in->off == in->len)
|
358
|
+
return 0;
|
359
|
+
|
360
|
+
available = in->len - in->off;
|
361
|
+
toread = len < available ? len : available;
|
362
|
+
memcpy(buf, in->buffer + in->off, toread);
|
363
|
+
in->off += toread;
|
364
|
+
return toread;
|
365
|
+
}
|
366
|
+
|
367
|
+
static ssize_t
|
368
|
+
int_b64_read(krypt_b64_buffer *in, uint8_t *buf, size_t len)
|
369
|
+
{
|
370
|
+
size_t total = 0;
|
371
|
+
|
372
|
+
while (total != len && !(in->off == in->len && in->eof)) {
|
373
|
+
if (in->off == in->len) {
|
374
|
+
if (int_b64_fill(in) == BINYO_ERR) return BINYO_ERR;
|
375
|
+
}
|
376
|
+
total += int_consume_bytes(in, buf + total, len - total);
|
377
|
+
}
|
378
|
+
|
379
|
+
if (total == 0 && in->eof)
|
380
|
+
return BINYO_IO_EOF;
|
381
|
+
|
382
|
+
if (total > SSIZE_MAX) {
|
383
|
+
krypt_error_add("Return size too large: %ld", total);
|
384
|
+
return BINYO_ERR;
|
385
|
+
}
|
386
|
+
return (ssize_t) total;
|
387
|
+
}
|
388
|
+
|
389
|
+
static ssize_t
|
390
|
+
int_pem_read(binyo_instream *instream, uint8_t *buf, size_t len)
|
391
|
+
{
|
392
|
+
krypt_instream_pem *in;
|
393
|
+
if (!buf) return BINYO_ERR;
|
394
|
+
int_safe_cast(in, instream);
|
395
|
+
return int_b64_read(in->buffer, buf, len);
|
396
|
+
}
|
397
|
+
|
Binary file
|
@@ -0,0 +1,238 @@
|
|
1
|
+
/*
|
2
|
+
* krypt-core API - C implementation
|
3
|
+
*
|
4
|
+
* Copyright (c) 2011-2013
|
5
|
+
* Hiroshi Nakamura <nahi@ruby-lang.org>
|
6
|
+
* Martin Bosslet <martin.bosslet@gmail.com>
|
7
|
+
* All rights reserved.
|
8
|
+
*
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
10
|
+
* a copy of this software and associated documentation files (the
|
11
|
+
* "Software"), to deal in the Software without restriction, including
|
12
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
13
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
14
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
15
|
+
* the following conditions:
|
16
|
+
*
|
17
|
+
* The above copyright notice and this permission notice shall be
|
18
|
+
* included in all copies or substantial portions of the Software.
|
19
|
+
*
|
20
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
21
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
23
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
24
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
25
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
26
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
|
+
*/
|
28
|
+
|
29
|
+
#include "krypt-core.h"
|
30
|
+
|
31
|
+
#ifndef HAVE_RB_STR_ENCODE
|
32
|
+
VALUE
|
33
|
+
rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts)
|
34
|
+
{
|
35
|
+
rb_encoding *enc = rb_enc_get(to);
|
36
|
+
rb_enc_associate(str, enc);
|
37
|
+
return str;
|
38
|
+
}
|
39
|
+
#endif
|
40
|
+
|
41
|
+
#ifndef HAVE_GMTIME_R
|
42
|
+
struct tm *
|
43
|
+
krypt_gmtime_r(const time_t *tp, struct tm *result)
|
44
|
+
{
|
45
|
+
struct tm *t = gmtime(tp);
|
46
|
+
if (t) *result = *t;
|
47
|
+
return t;
|
48
|
+
}
|
49
|
+
#endif
|
50
|
+
|
51
|
+
#ifdef HAVE_RB_BIG_PACK
|
52
|
+
int
|
53
|
+
krypt_asn1_encode_bignum(VALUE bignum, uint8_t **out, size_t *outlen)
|
54
|
+
{
|
55
|
+
int len, i, j;
|
56
|
+
long num_longs, biglen, divisor;
|
57
|
+
unsigned long *longs;
|
58
|
+
uint8_t *bytes;
|
59
|
+
uint8_t *ptr;
|
60
|
+
uint8_t msb;
|
61
|
+
unsigned long l;
|
62
|
+
|
63
|
+
biglen = RBIGNUM_LEN(bignum);
|
64
|
+
divisor = SIZEOF_LONG / SIZEOF_BDIGITS;
|
65
|
+
num_longs = (biglen % divisor) == 0 ? biglen / divisor : biglen / divisor + 1;
|
66
|
+
longs = ALLOC_N(unsigned long, num_longs);
|
67
|
+
rb_big_pack(bignum, longs, num_longs);
|
68
|
+
msb = longs[num_longs - 1] >> (SIZEOF_LONG * CHAR_BIT - 1);
|
69
|
+
|
70
|
+
if (RBIGNUM_SIGN(bignum) == ((msb & 1) == 1)) {
|
71
|
+
/* We can't use int_encode_integer here because longs are unsigned */
|
72
|
+
len = num_longs * SIZEOF_LONG + 1;
|
73
|
+
bytes = ALLOC_N(uint8_t, len);
|
74
|
+
ptr = bytes;
|
75
|
+
*ptr++ = RBIGNUM_SIGN(bignum) ? 0x00 : 0xff;
|
76
|
+
}
|
77
|
+
else {
|
78
|
+
uint8_t *buf;
|
79
|
+
size_t encoded;
|
80
|
+
|
81
|
+
encoded = krypt_asn1_encode_integer(longs[num_longs - 1], &buf);
|
82
|
+
len = encoded + (num_longs - 1) * SIZEOF_LONG;
|
83
|
+
bytes = ALLOC_N(uint8_t, len);
|
84
|
+
ptr = bytes;
|
85
|
+
memcpy(ptr, buf, encoded);
|
86
|
+
ptr += encoded;
|
87
|
+
--num_longs;
|
88
|
+
xfree(buf);
|
89
|
+
}
|
90
|
+
for (i = num_longs - 1; i >= 0; --i) {
|
91
|
+
l = longs[i];
|
92
|
+
for (j = 0; j < SIZEOF_LONG; ++j) {
|
93
|
+
ptr[SIZEOF_LONG - j - 1] = l & 0xff;
|
94
|
+
l >>= CHAR_BIT;
|
95
|
+
}
|
96
|
+
ptr += SIZEOF_LONG;
|
97
|
+
}
|
98
|
+
xfree(longs);
|
99
|
+
*out = bytes;
|
100
|
+
*outlen = ptr - bytes;
|
101
|
+
return KRYPT_OK;
|
102
|
+
}
|
103
|
+
#else
|
104
|
+
int
|
105
|
+
krypt_asn1_encode_bignum(VALUE bignum, uint8_t **out, size_t *outlen)
|
106
|
+
{
|
107
|
+
VALUE hexstr;
|
108
|
+
int sign;
|
109
|
+
char *hexstrbytes;
|
110
|
+
int free_hex = 0;
|
111
|
+
long hexstrlen;
|
112
|
+
uint8_t *numbytes;
|
113
|
+
size_t numlen;
|
114
|
+
|
115
|
+
sign = RBIGNUM_NEGATIVE_P(bignum);
|
116
|
+
|
117
|
+
hexstr = rb_funcall(bignum, rb_intern("to_s"), 1, INT2NUM(16));
|
118
|
+
hexstrbytes = (char *) RSTRING_PTR(hexstr);
|
119
|
+
hexstrlen = RSTRING_LEN(hexstr);
|
120
|
+
|
121
|
+
if (sign) {
|
122
|
+
hexstrbytes++;
|
123
|
+
hexstrlen--; /* discard '-' */
|
124
|
+
}
|
125
|
+
|
126
|
+
if (hexstrlen % 2) {
|
127
|
+
/* pad with leading 0 */
|
128
|
+
char *padded = ALLOC_N(char, hexstrlen + 1);
|
129
|
+
padded[0] = '0';
|
130
|
+
memcpy(padded +1, hexstrbytes, hexstrlen);
|
131
|
+
hexstrbytes = padded;
|
132
|
+
hexstrlen++;
|
133
|
+
free_hex = 1;
|
134
|
+
}
|
135
|
+
|
136
|
+
if (krypt_hex_decode(hexstrbytes, hexstrlen, &numbytes, &numlen) == KRYPT_ERR) {
|
137
|
+
if (free_hex) xfree(hexstrbytes);
|
138
|
+
return KRYPT_ERR;
|
139
|
+
}
|
140
|
+
if (sign) {
|
141
|
+
krypt_compute_twos_complement(numbytes, numbytes, numlen);
|
142
|
+
} else if (numbytes[0] & 0x80) {
|
143
|
+
uint8_t *normalized = ALLOC_N(uint8_t, numlen + 1);
|
144
|
+
normalized[0] = 0x0;
|
145
|
+
memcpy(normalized + 1, numbytes, numlen);
|
146
|
+
xfree(numbytes);
|
147
|
+
numlen++;
|
148
|
+
numbytes = normalized;
|
149
|
+
}
|
150
|
+
|
151
|
+
if (free_hex) xfree(hexstrbytes);
|
152
|
+
*out = numbytes;
|
153
|
+
*outlen = numlen;
|
154
|
+
return KRYPT_OK;
|
155
|
+
}
|
156
|
+
#endif
|
157
|
+
|
158
|
+
#ifdef HAVE_RB_BIG_PACK
|
159
|
+
int
|
160
|
+
krypt_asn1_decode_bignum(uint8_t *bytes, size_t len, VALUE *out)
|
161
|
+
{
|
162
|
+
long num_longs;
|
163
|
+
int i, j, pos, sign;
|
164
|
+
unsigned long *longs;
|
165
|
+
long l;
|
166
|
+
VALUE value;
|
167
|
+
|
168
|
+
sign = bytes[0] & 0x80;
|
169
|
+
num_longs = (len - 1) / SIZEOF_LONG + 1;
|
170
|
+
longs = ALLOC_N(unsigned long, num_longs);
|
171
|
+
for (i = 0; i < num_longs; ++i) {
|
172
|
+
l = 0;
|
173
|
+
for (j = 0; j < SIZEOF_LONG; ++j) {
|
174
|
+
pos = len - i * SIZEOF_LONG - j - 1;
|
175
|
+
if (pos >= 0) {
|
176
|
+
l += ((long)(bytes[pos] & 0xff) << (j * CHAR_BIT));
|
177
|
+
}
|
178
|
+
else if (sign) {
|
179
|
+
l |= ((long)0xff << (j * CHAR_BIT));
|
180
|
+
}
|
181
|
+
}
|
182
|
+
longs[i] = l;
|
183
|
+
}
|
184
|
+
value = rb_big_unpack(longs, num_longs);
|
185
|
+
if (TYPE(value) == T_BIGNUM) {
|
186
|
+
RBIGNUM_SET_SIGN(value, !sign);
|
187
|
+
}
|
188
|
+
xfree(longs);
|
189
|
+
*out = value;
|
190
|
+
return KRYPT_OK;
|
191
|
+
}
|
192
|
+
#else
|
193
|
+
int krypt_asn1_decode_bignum(uint8_t *bytes, size_t len, VALUE *out)
|
194
|
+
{
|
195
|
+
int sign;
|
196
|
+
size_t hexlen;
|
197
|
+
uint8_t *absolute;
|
198
|
+
int free_abs = 0;
|
199
|
+
char *hexnum;
|
200
|
+
char *chexnum;
|
201
|
+
|
202
|
+
sign = bytes[0] & 0x80;
|
203
|
+
if (sign) {
|
204
|
+
absolute = ALLOC_N(uint8_t, len);
|
205
|
+
krypt_compute_twos_complement(absolute, bytes, len);
|
206
|
+
free_abs = 1;
|
207
|
+
} else {
|
208
|
+
absolute = bytes;
|
209
|
+
if (absolute[0] == 0x0) {
|
210
|
+
absolute++;
|
211
|
+
len--;
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
if (krypt_hex_encode(absolute, len, &hexnum, &hexlen) == KRYPT_ERR) {
|
216
|
+
if (free_abs) xfree(absolute);
|
217
|
+
return KRYPT_ERR;
|
218
|
+
}
|
219
|
+
|
220
|
+
if (sign) {
|
221
|
+
chexnum = ALLOC_N(char, hexlen + 2);
|
222
|
+
chexnum[0] = '-';
|
223
|
+
memcpy(chexnum + 1, hexnum, hexlen);
|
224
|
+
chexnum[hexlen + 1] = '\0';
|
225
|
+
} else {
|
226
|
+
chexnum = ALLOC_N(char, hexlen + 1);
|
227
|
+
memcpy(chexnum, hexnum, hexlen);
|
228
|
+
chexnum[hexlen] = '\0';
|
229
|
+
}
|
230
|
+
|
231
|
+
*out = rb_cstr2inum(chexnum, 16);
|
232
|
+
if (free_abs) xfree(absolute);
|
233
|
+
xfree(hexnum);
|
234
|
+
xfree(chexnum);
|
235
|
+
return KRYPT_OK;
|
236
|
+
}
|
237
|
+
#endif
|
238
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
/*
|
2
|
+
* krypt-core API - C implementation
|
3
|
+
*
|
4
|
+
* Copyright (c) 2011-2013
|
5
|
+
* Hiroshi Nakamura <nahi@ruby-lang.org>
|
6
|
+
* Martin Bosslet <martin.bosslet@gmail.com>
|
7
|
+
* All rights reserved.
|
8
|
+
*
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
10
|
+
* a copy of this software and associated documentation files (the
|
11
|
+
* "Software"), to deal in the Software without restriction, including
|
12
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
13
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
14
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
15
|
+
* the following conditions:
|
16
|
+
*
|
17
|
+
* The above copyright notice and this permission notice shall be
|
18
|
+
* included in all copies or substantial portions of the Software.
|
19
|
+
*
|
20
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
21
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
23
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
24
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
25
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
26
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
|
+
*/
|
28
|
+
|
29
|
+
#ifndef _KRYPT_MISSING_H_
|
30
|
+
#define _KRYPT_MISSING_H_
|
31
|
+
|
32
|
+
#include RUBY_EXTCONF_H
|
33
|
+
|
34
|
+
#ifndef HAVE_RB_ENUMERATORIZE
|
35
|
+
#define KRYPT_RETURN_ENUMERATOR(enumerable, id) \
|
36
|
+
do { \
|
37
|
+
if (!rb_block_given_p()) \
|
38
|
+
return rb_funcall((enumerable), rb_intern("enum_for"), 1, ID2SYM((id))); \
|
39
|
+
} while (0)
|
40
|
+
#else
|
41
|
+
#define KRYPT_RETURN_ENUMERATOR(enumerable, id) \
|
42
|
+
do { \
|
43
|
+
if(!rb_block_given_p()) \
|
44
|
+
RETURN_ENUMERATOR((enumerable), 0, 0); \
|
45
|
+
} while (0)
|
46
|
+
#endif
|
47
|
+
|
48
|
+
#ifndef HAVE_RB_STR_ENCODE
|
49
|
+
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts);
|
50
|
+
#endif
|
51
|
+
|
52
|
+
#ifndef HAVE_GMTIME_R
|
53
|
+
#include <time.h>
|
54
|
+
struct tm *krypt_gmtime_r(const time_t *tp, struct tm *result);
|
55
|
+
#define gmtime_r(t, tm) krypt_gmtime_r((t), (tm))
|
56
|
+
#endif
|
57
|
+
|
58
|
+
int krypt_asn1_encode_bignum(VALUE bignum, uint8_t **out, size_t *len);
|
59
|
+
int krypt_asn1_decode_bignum(uint8_t *bytes, size_t len, VALUE *out);
|
60
|
+
|
61
|
+
#endif /* KRYPT_MISSING_H */
|
62
|
+
|
Binary file
|