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,391 @@
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
+ VALUE mKryptDigest;
32
+ VALUE eKryptDigestError;
33
+
34
+ VALUE cKryptNativeDigest;
35
+
36
+ /** public internal digest API **/
37
+
38
+ #define int_check_provider_has(p, m) if (!(p) || !(p)->m) return NULL;
39
+ #define int_check_digest_has(d, m) if (!(d) || !(d)->methods || !(d)->methods->m) return KRYPT_ERR;
40
+
41
+ krypt_md *
42
+ krypt_md_oid_new(krypt_provider *provider, const char *oid)
43
+ {
44
+ int_check_provider_has(provider, md_new_oid);
45
+ return provider->md_new_oid(provider, oid);
46
+ }
47
+
48
+ krypt_md *
49
+ krypt_md_name_new(krypt_provider *provider, const char *name)
50
+ {
51
+ int_check_provider_has(provider, md_new_name);
52
+ return provider->md_new_name(provider, name);
53
+ }
54
+
55
+ krypt_md *
56
+ krypt_md_new(krypt_provider *provider, const char *name_or_oid)
57
+ {
58
+ krypt_md *ret = NULL;
59
+ if ((ret = krypt_md_name_new(provider, name_or_oid)))
60
+ return ret;
61
+ return krypt_md_oid_new(provider, name_or_oid);
62
+ }
63
+
64
+ int
65
+ krypt_md_reset(krypt_md *md)
66
+ {
67
+ int_check_digest_has(md, md_reset);
68
+ return md->methods->md_reset(md);
69
+ }
70
+
71
+ int
72
+ krypt_md_update(krypt_md *md, const void *data, size_t len)
73
+ {
74
+ int_check_digest_has(md, md_update);
75
+ return md->methods->md_update(md, data, len);
76
+ }
77
+
78
+ int
79
+ krypt_md_final(krypt_md *md, uint8_t **digest, size_t *len)
80
+ {
81
+ int_check_digest_has(md, md_final);
82
+ if (md->methods->md_final(md, digest, len) == KRYPT_ERR) return KRYPT_ERR;
83
+ return krypt_md_reset(md);
84
+ }
85
+
86
+ int
87
+ krypt_md_digest(krypt_md *md, const uint8_t *data, size_t len, uint8_t **digest, size_t *digest_len)
88
+ {
89
+ int_check_digest_has(md, md_digest);
90
+ if(md->methods->md_digest(md, data, len, digest, digest_len) == KRYPT_ERR) return KRYPT_ERR;
91
+ return krypt_md_reset(md);
92
+ }
93
+
94
+ int
95
+ krypt_md_digest_length(krypt_md *md, size_t *len)
96
+ {
97
+ int_check_digest_has(md, md_digest_length);
98
+ return md->methods->md_digest_length(md, len);
99
+ }
100
+
101
+ int
102
+ krypt_md_block_length(krypt_md *md, size_t *len)
103
+ {
104
+ int_check_digest_has(md, md_block_length);
105
+ return md->methods->md_block_length(md, len);
106
+ }
107
+
108
+ int
109
+ krypt_md_name(krypt_md *md, const char **name)
110
+ {
111
+ int_check_digest_has(md, md_name);
112
+ return md->methods->md_name(md, name);
113
+ }
114
+
115
+ void
116
+ krypt_md_mark(krypt_md *md)
117
+ {
118
+ if (!md) return;
119
+ if (md->methods->mark)
120
+ md->methods->mark(md);
121
+ }
122
+
123
+ void
124
+ krypt_md_free(krypt_md *md)
125
+ {
126
+ if (!md) return;
127
+ md->methods->free(md);
128
+ }
129
+
130
+ /** Digest class implementation **/
131
+
132
+ VALUE
133
+ krypt_digest_new(krypt_md *md)
134
+ {
135
+ VALUE obj;
136
+
137
+ obj = Data_Wrap_Struct(cKryptNativeDigest, krypt_md_mark, krypt_md_free, md);
138
+ return obj;
139
+ }
140
+
141
+ #define int_md_get(obj, md) \
142
+ do { \
143
+ Data_Get_Struct((obj), krypt_md, (md)); \
144
+ if (!(md)) { \
145
+ rb_raise(eKryptError, "Uninitialized krypt_md"); \
146
+ } \
147
+ } while (0)
148
+
149
+ /*
150
+ * call-seq:
151
+ * digest.reset -> self
152
+ *
153
+ * Resets the Digest in the sense that any Digest#update that has been
154
+ * performed is abandoned and the Digest is set to its initial state again.
155
+ *
156
+ */
157
+ static VALUE
158
+ krypt_digest_reset(VALUE self)
159
+ {
160
+ krypt_md *md;
161
+
162
+ int_md_get(self, md);
163
+ if (krypt_md_reset(md) == KRYPT_ERR) {
164
+ rb_raise(eKryptDigestError, "Error while resetting digest");
165
+ }
166
+ return self;
167
+ }
168
+
169
+ /*
170
+ * call-seq:
171
+ * digest.update(string) -> aString
172
+ *
173
+ * Not every message digest can be computed in one single pass. If a message
174
+ * digest is to be computed from several subsequent sources, then each may
175
+ * be passed individually to the Digest instance.
176
+ *
177
+ * === Example
178
+ * digest = Krypt::Digest::SHA256.new
179
+ * digest.update('First input')
180
+ * digest << 'Second input' # equivalent to digest.update('Second input')
181
+ * result = digest.digest
182
+ *
183
+ */
184
+ static VALUE
185
+ krypt_digest_update(VALUE self, VALUE data)
186
+ {
187
+ krypt_md *md;
188
+ uint8_t *bytes;
189
+ size_t len;
190
+
191
+ int_md_get(self, md);
192
+ StringValue(data);
193
+ bytes = (uint8_t *) RSTRING_PTR(data);
194
+ len = (size_t) RSTRING_LEN(data);
195
+ if (krypt_md_update(md, bytes, len) == KRYPT_ERR) {
196
+ rb_raise(eKryptDigestError, "Error while updating digest");
197
+ }
198
+ return self;
199
+ }
200
+
201
+ static VALUE
202
+ int_digest_data(krypt_md *md, VALUE data)
203
+ {
204
+ uint8_t *bytes;
205
+ size_t len;
206
+ uint8_t *digest;
207
+ size_t digest_len;
208
+ VALUE ret;
209
+
210
+ StringValue(data);
211
+ bytes = (uint8_t *) RSTRING_PTR(data);
212
+ len = (size_t) RSTRING_LEN(data);
213
+ if (krypt_md_digest(md, bytes, len, &digest, &digest_len) == KRYPT_ERR) {
214
+ rb_raise(eKryptDigestError, "Error while computing digest");
215
+ }
216
+ ret = rb_str_new((const char *) digest, digest_len);
217
+ xfree(digest);
218
+ return ret;
219
+ }
220
+
221
+ static VALUE
222
+ int_digest_final(krypt_md *md)
223
+ {
224
+ uint8_t *digest;
225
+ size_t len;
226
+ VALUE ret;
227
+ if (krypt_md_final(md, &digest, &len) == KRYPT_ERR) {
228
+ rb_raise(eKryptDigestError, "Error while finalizing digest");
229
+ }
230
+ ret = rb_str_new((const char *) digest, len);
231
+ xfree(digest);
232
+ return ret;
233
+ }
234
+
235
+ /*
236
+ * call-seq:
237
+ * digest.digest([string]) -> String
238
+ *
239
+ * When called with no arguments, the result will be the hash of the data that
240
+ * has been fed to this Digest instance so far. If called with a String
241
+ * argument, the hash of that argument will be computed.
242
+ *
243
+ * === Example
244
+ * digest = Krypt::Digest::SHA256.new
245
+ * result = digest.digest('First input')
246
+ *
247
+ * is equivalent to
248
+ *
249
+ * digest = Krypt::Digest::SHA256.new
250
+ * digest << 'First input' # equivalent to digest.update('Second input')
251
+ * result = digest.digest
252
+ *
253
+ */
254
+ static VALUE
255
+ krypt_digest_digest(int argc, VALUE *args, VALUE self)
256
+ {
257
+ krypt_md *md;
258
+ VALUE data;
259
+
260
+ rb_scan_args(argc, args, "01", &data);
261
+ int_md_get(self, md);
262
+ if (!(NIL_P(data)))
263
+ return int_digest_data(md, data);
264
+ else
265
+ return int_digest_final(md);
266
+ }
267
+
268
+ /*
269
+ * call-seq:
270
+ * digest.hexdigest([string]) -> String
271
+ *
272
+ * Works the with the same semantics as Digest#digest with the difference that
273
+ * instead of the raw bytes the hex-encoded form of the raw representation is
274
+ * returned.
275
+ */
276
+ static VALUE
277
+ krypt_digest_hexdigest(int argc, VALUE *args, VALUE self)
278
+ {
279
+ VALUE digest, ret;
280
+ uint8_t *bytes;
281
+ size_t len;
282
+
283
+ digest = krypt_digest_digest(argc, args, self);
284
+ if (krypt_hex_encode((uint8_t *) RSTRING_PTR(digest), RSTRING_LEN(digest), &bytes, &len) == KRYPT_ERR)
285
+ rb_raise(eKryptDigestError, "Error while hex-encoding digest");
286
+ ret = rb_str_new((const char *) bytes, len);
287
+ xfree(bytes);
288
+ return ret;
289
+ }
290
+
291
+ /*
292
+ * call-seq:
293
+ * digest.digest_length -> integer
294
+ *
295
+ * Returns the output size of the digest, i.e. the length in bytes of the
296
+ * final message digest result.
297
+ *
298
+ * === Example
299
+ * digest = Krypt::Digest::SHA1.new
300
+ * puts digest.digest_length # => 20
301
+ *
302
+ */
303
+ static VALUE
304
+ krypt_digest_digest_length(VALUE self)
305
+ {
306
+ krypt_md *md;
307
+ size_t len;
308
+
309
+ int_md_get(self, md);
310
+ if (krypt_md_digest_length(md, &len) == KRYPT_ERR) {
311
+ rb_raise(eKryptDigestError, "Error while getting digest length");
312
+ }
313
+ return INT2NUM(len);
314
+ }
315
+
316
+ /*
317
+ * call-seq:
318
+ * digest.block_length -> integer
319
+ *
320
+ * Returns the block length of the digest algorithm, i.e. the length in bytes
321
+ * of an individual block. Most modern algorithms partition a message to be
322
+ * digested into a sequence of fix-sized blocks that are processed
323
+ * consecutively.
324
+ *
325
+ * === Example
326
+ * digest = Krypt::Digest::SHA1.new
327
+ * puts digest.block_length # => 64
328
+ */
329
+ static VALUE
330
+ krypt_digest_block_length(VALUE self)
331
+ {
332
+ krypt_md *md;
333
+ size_t len;
334
+
335
+ int_md_get(self, md);
336
+ if (krypt_md_block_length(md, &len) == KRYPT_ERR) {
337
+ rb_raise(eKryptDigestError, "Error while getting digest block length");
338
+ }
339
+ return INT2NUM(len);
340
+ }
341
+
342
+ /*
343
+ * call-seq:
344
+ * digest.name -> string
345
+ *
346
+ * Returns the sn of this Digest instance.
347
+ *
348
+ * === Example
349
+ * digest = Krypt::Digest::SHA512.new
350
+ * puts digest.name # => SHA512
351
+ *
352
+ */
353
+ static VALUE
354
+ krypt_digest_name(VALUE self)
355
+ {
356
+ krypt_md *md;
357
+ const char *name;
358
+
359
+ int_md_get(self, md);
360
+ if (krypt_md_name(md, &name) == KRYPT_ERR) {
361
+ rb_raise(eKryptDigestError, "Error while getting digest name");
362
+ }
363
+ return rb_str_new2(name);
364
+ }
365
+
366
+ void
367
+ Init_krypt_digest(void)
368
+ {
369
+ #if 0
370
+ mKrypt = rb_define_module("Krypt"); /* Let RDoc know */
371
+ #endif
372
+
373
+ mKryptDigest = rb_path2class("Krypt::Digest");
374
+ eKryptDigestError = rb_path2class("Krypt::Digest::DigestError");
375
+
376
+ /* Document-class: Krypt::Digest::NativeDigest
377
+ * Native C implementation of the Krypt::Digest interface.
378
+ */
379
+ cKryptNativeDigest = rb_define_class_under(mKryptDigest, "NativeDigest", rb_cObject);
380
+
381
+ rb_define_method(cKryptNativeDigest, "reset", krypt_digest_reset, 0);
382
+ rb_define_method(cKryptNativeDigest, "update", krypt_digest_update, 1);
383
+ rb_define_alias(cKryptNativeDigest, "<<", "update");
384
+ rb_define_method(cKryptNativeDigest, "digest", krypt_digest_digest, -1);
385
+ rb_define_method(cKryptNativeDigest, "hexdigest", krypt_digest_hexdigest, -1);
386
+ rb_define_method(cKryptNativeDigest, "digest_length", krypt_digest_digest_length, 0);
387
+ rb_define_method(cKryptNativeDigest, "block_length", krypt_digest_block_length, 0);
388
+ rb_define_method(cKryptNativeDigest, "name", krypt_digest_name, 0);
389
+ rb_undef_method(CLASS_OF(cKryptNativeDigest), "new"); /* private constructor */
390
+ }
391
+
@@ -0,0 +1,51 @@
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_DIGEST_H_
30
+ #define _KRYPT_DIGEST_H_
31
+
32
+ extern VALUE mKryptDigest;
33
+ extern VALUE eKryptDigestError;
34
+
35
+ extern VALUE cKryptNativeDigest;
36
+
37
+ krypt_md *krypt_md_new(krypt_provider *provider, const char *name_or_oid);
38
+ krypt_md *krypt_md_oid_new(krypt_provider *provider, const char *oid);
39
+ krypt_md *krypt_md_name_new(krypt_provider *provider, const char *name);
40
+
41
+ int krypt_md_update(krypt_md *md, const void *data, size_t len);
42
+ int krypt_md_final(krypt_md *md, uint8_t **digest, size_t *len);
43
+ int krypt_md_digest(krypt_md *md, const uint8_t *data, size_t len, uint8_t **digest, size_t *digest_len);
44
+ void krypt_md_mark(krypt_md *md);
45
+ void krypt_md_free(krypt_md *md);
46
+
47
+ VALUE krypt_digest_new(krypt_md *md);
48
+
49
+ void Init_krypt_digest(void);
50
+
51
+ #endif /* _KRYPT_DIGEST_H_ */
Binary file
@@ -0,0 +1,221 @@
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
+ #include <stdarg.h>
31
+
32
+ typedef struct krypt_err_stack_elem_st krypt_err_stack_elem;
33
+
34
+ typedef struct krypt_err_stack_st {
35
+ int count;
36
+ krypt_err_stack_elem *head;
37
+ } krypt_err_stack;
38
+
39
+ struct krypt_err_stack_elem_st {
40
+ char *message;
41
+ size_t len;
42
+ krypt_err_stack_elem *prev;
43
+ };
44
+
45
+ static krypt_err_stack err_stack = { 0 };
46
+
47
+ #define int_err_stack_empty() (err_stack.count == 0)
48
+
49
+ static void
50
+ int_err_stack_push(char *message, size_t len)
51
+ {
52
+ krypt_err_stack_elem *elem;
53
+
54
+ elem = ALLOC(krypt_err_stack_elem);
55
+ elem->message = message;
56
+ elem->len = len;
57
+ elem->prev = err_stack.head;
58
+ err_stack.head = elem;
59
+ err_stack.count++;
60
+ }
61
+
62
+ static char *
63
+ int_err_stack_pop()
64
+ {
65
+ char *message;
66
+ krypt_err_stack_elem *head = err_stack.head;
67
+
68
+ if (!head) return NULL;
69
+
70
+ err_stack.head = head->prev;
71
+ message = head->message;
72
+ xfree(head);
73
+ err_stack.count--;
74
+ return message;
75
+ }
76
+
77
+ int
78
+ krypt_has_errors(void)
79
+ {
80
+ return !int_err_stack_empty();
81
+ }
82
+
83
+ int
84
+ krypt_error_message(char *buf, int buf_len)
85
+ {
86
+ krypt_err_stack_elem *head = err_stack.head;
87
+ int len = 0;
88
+
89
+ while (head) {
90
+ int cur_len;
91
+ char *message = head->message;
92
+ cur_len = snprintf(buf + len, buf_len, "%s%s", (len ? ": " : ""), message);
93
+ if (cur_len > 0)
94
+ len += cur_len;
95
+ head = head->prev;
96
+ }
97
+
98
+ return len;
99
+ }
100
+
101
+ void
102
+ krypt_error_add(const char *format, ...)
103
+ {
104
+ char *buf;
105
+ int len = 0;
106
+ va_list args;
107
+
108
+ va_start(args, format);
109
+ buf = ALLOC_N(char, BUFSIZ);
110
+ if ((len = vsnprintf(buf, BUFSIZ, format, args)) < 0) return;
111
+ int_err_stack_push(buf, len);
112
+ va_end(args);
113
+ }
114
+
115
+ static int
116
+ int_add_binyo_errors(char *buf, int len)
117
+ {
118
+ int l = 0;
119
+
120
+ if (binyo_has_errors()) {
121
+ int cur_len;
122
+ if ((cur_len = snprintf(buf + l, len, "%s", ": ")) > 0)
123
+ l += cur_len;
124
+ if ((cur_len = binyo_error_message(buf + l, len)) > 0)
125
+ l += cur_len;
126
+ }
127
+
128
+ return l;
129
+ }
130
+
131
+ static int
132
+ int_error_msg_create(char *buf, int len, const char *format, va_list args)
133
+ {
134
+ int l;
135
+
136
+ if ((l = vsnprintf(buf, len, format, args)) < 0) {
137
+ return -1;
138
+ }
139
+
140
+ while (!int_err_stack_empty()) {
141
+ int cur_len;
142
+ char *message = int_err_stack_pop();
143
+ cur_len = snprintf(buf + l, len, "%s%s", (l ? ": " : ""), message);
144
+ xfree(message);
145
+ if (cur_len > 0)
146
+ l += cur_len;
147
+ }
148
+
149
+ l += int_add_binyo_errors(buf + l, len);
150
+ binyo_error_clear();
151
+
152
+ return l;
153
+ }
154
+
155
+ static VALUE
156
+ int_error_create(VALUE exception_class, const char *format, va_list args)
157
+ {
158
+ char buf[BUFSIZ];
159
+ int len = 0;
160
+
161
+ if ((len = int_error_msg_create(buf, BUFSIZ, format, args)) < 0) {
162
+ return rb_funcall(exception_class, rb_intern("new"), 0);
163
+ }
164
+
165
+ return rb_exc_new(exception_class, buf, len);
166
+ }
167
+
168
+ static VALUE
169
+ int_error_enhance(VALUE exception_class, VALUE active_exc, const char *format, va_list args)
170
+ {
171
+ char buf[BUFSIZ];
172
+ int len;
173
+ VALUE orig_msg;
174
+ long orig_len;
175
+ const char *active_name = rb_class2name(CLASS_OF(active_exc));
176
+ size_t active_name_len = strlen(active_name);
177
+
178
+ if ((len = int_error_msg_create(buf, BUFSIZ, format, args)) < 0) {
179
+ return active_exc;
180
+ }
181
+
182
+ orig_msg = rb_funcall(active_exc, rb_intern("message"), 0);
183
+ StringValueCStr(orig_msg);
184
+ orig_len = RSTRING_LEN(orig_msg);
185
+ if (len <= BUFSIZ - ( (int) active_name_len ) - orig_len - 4) {
186
+ strcat(buf, ": ");
187
+ strcat(buf, active_name);
188
+ strcat(buf, ": ");
189
+ strcat(buf, RSTRING_PTR(orig_msg));
190
+ len += active_name_len + orig_len + 4;
191
+ }
192
+
193
+ return rb_exc_new(exception_class, buf, len);
194
+ }
195
+
196
+ void
197
+ krypt_error_raise(VALUE exception_class, const char *format, ...)
198
+ {
199
+ VALUE exc;
200
+ VALUE active_exc;
201
+ va_list args;
202
+
203
+ va_start(args, format);
204
+ active_exc = rb_errinfo();
205
+ if (NIL_P(active_exc)) {
206
+ exc = int_error_create(exception_class, format, args);
207
+ } else {
208
+ exc = int_error_enhance(exception_class, active_exc, format, args);
209
+ }
210
+ va_end(args);
211
+ rb_exc_raise(exc);
212
+ }
213
+
214
+ void
215
+ krypt_error_clear(void)
216
+ {
217
+ while (!int_err_stack_empty()) {
218
+ xfree(int_err_stack_pop());
219
+ }
220
+ }
221
+
@@ -0,0 +1,46 @@
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_ERROR_H_
30
+ #define _KRYPT_ERROR_H_
31
+
32
+ #define KRYPT_OK 1
33
+ #define KRYPT_ERR -1
34
+
35
+ #define KRYPT_ASN1_EOF -2
36
+
37
+ void krypt_error_add(const char *format, ...);
38
+
39
+ int krypt_has_errors(void);
40
+ int krypt_error_message(char *buf, int buf_len);
41
+ VALUE krypt_error_create(VALUE exception_class, const char *format, ...);
42
+ void krypt_error_raise(VALUE exception_class, const char *format, ...);
43
+ void krypt_error_clear(void);
44
+
45
+ #endif /* KRYPT_ERROR_H */
46
+
Binary file