krypt-core 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/LICENSE +20 -0
  2. data/ext/krypt/core/Makefile +221 -0
  3. data/ext/krypt/core/binyo-error.h +40 -0
  4. data/ext/krypt/core/binyo-io-buffer.h +54 -0
  5. data/ext/krypt/core/binyo-io.h +131 -0
  6. data/ext/krypt/core/extconf.h +8 -0
  7. data/ext/krypt/core/extconf.rb +80 -0
  8. data/ext/krypt/core/krypt-core.c +110 -0
  9. data/ext/krypt/core/krypt-core.h +97 -0
  10. data/ext/krypt/core/krypt-core.o +0 -0
  11. data/ext/krypt/core/krypt-provider.h +86 -0
  12. data/ext/krypt/core/krypt_asn1-internal.c +681 -0
  13. data/ext/krypt/core/krypt_asn1-internal.h +117 -0
  14. data/ext/krypt/core/krypt_asn1-internal.o +0 -0
  15. data/ext/krypt/core/krypt_asn1.c +2109 -0
  16. data/ext/krypt/core/krypt_asn1.h +88 -0
  17. data/ext/krypt/core/krypt_asn1.o +0 -0
  18. data/ext/krypt/core/krypt_asn1_codec.c +973 -0
  19. data/ext/krypt/core/krypt_asn1_codec.o +0 -0
  20. data/ext/krypt/core/krypt_asn1_in_adapter.c +178 -0
  21. data/ext/krypt/core/krypt_asn1_in_adapter.o +0 -0
  22. data/ext/krypt/core/krypt_asn1_in_chunked.c +292 -0
  23. data/ext/krypt/core/krypt_asn1_in_chunked.o +0 -0
  24. data/ext/krypt/core/krypt_asn1_in_definite.c +156 -0
  25. data/ext/krypt/core/krypt_asn1_in_definite.o +0 -0
  26. data/ext/krypt/core/krypt_asn1_parser.c +592 -0
  27. data/ext/krypt/core/krypt_asn1_parser.o +0 -0
  28. data/ext/krypt/core/krypt_asn1_template-internal.h +185 -0
  29. data/ext/krypt/core/krypt_asn1_template.c +459 -0
  30. data/ext/krypt/core/krypt_asn1_template.h +56 -0
  31. data/ext/krypt/core/krypt_asn1_template.o +0 -0
  32. data/ext/krypt/core/krypt_asn1_template_encoder.c +76 -0
  33. data/ext/krypt/core/krypt_asn1_template_encoder.o +0 -0
  34. data/ext/krypt/core/krypt_asn1_template_parser.c +1176 -0
  35. data/ext/krypt/core/krypt_asn1_template_parser.o +0 -0
  36. data/ext/krypt/core/krypt_b64-internal.h +38 -0
  37. data/ext/krypt/core/krypt_b64.c +391 -0
  38. data/ext/krypt/core/krypt_b64.h +41 -0
  39. data/ext/krypt/core/krypt_b64.o +0 -0
  40. data/ext/krypt/core/krypt_digest.c +391 -0
  41. data/ext/krypt/core/krypt_digest.h +51 -0
  42. data/ext/krypt/core/krypt_digest.o +0 -0
  43. data/ext/krypt/core/krypt_error.c +221 -0
  44. data/ext/krypt/core/krypt_error.h +46 -0
  45. data/ext/krypt/core/krypt_error.o +0 -0
  46. data/ext/krypt/core/krypt_hex-internal.h +36 -0
  47. data/ext/krypt/core/krypt_hex.c +255 -0
  48. data/ext/krypt/core/krypt_hex.h +41 -0
  49. data/ext/krypt/core/krypt_hex.o +0 -0
  50. data/ext/krypt/core/krypt_io.c +65 -0
  51. data/ext/krypt/core/krypt_io.h +56 -0
  52. data/ext/krypt/core/krypt_io.o +0 -0
  53. data/ext/krypt/core/krypt_io_in_pem.c +397 -0
  54. data/ext/krypt/core/krypt_io_in_pem.o +0 -0
  55. data/ext/krypt/core/krypt_missing.c +238 -0
  56. data/ext/krypt/core/krypt_missing.h +62 -0
  57. data/ext/krypt/core/krypt_missing.o +0 -0
  58. data/ext/krypt/core/krypt_pem.c +171 -0
  59. data/ext/krypt/core/krypt_pem.o +0 -0
  60. data/ext/krypt/core/krypt_provider-internal.h +40 -0
  61. data/ext/krypt/core/krypt_provider.c +136 -0
  62. data/ext/krypt/core/krypt_provider.o +0 -0
  63. data/ext/krypt/core/kryptcore.so +0 -0
  64. data/ext/krypt/core/mkmf.log +130 -0
  65. data/lib/krypt-core/version.rb +3 -0
  66. data/lib/krypt-core.rb +35 -0
  67. data/lib/kryptcore.so +0 -0
  68. data/spec/README +2 -0
  69. data/test/README +2 -0
  70. data/test/res/certificate.cer +0 -0
  71. data/test/resources.rb +48 -0
  72. data/test/scratch.rb +17 -0
  73. 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