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.
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