krypt-core 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
Binary file
|
@@ -0,0 +1,178 @@
|
|
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 cKryptASN1Instream;
|
32
|
+
|
33
|
+
typedef struct krypt_instream_adapter_st {
|
34
|
+
binyo_instream *in;
|
35
|
+
} krypt_instream_adapter;
|
36
|
+
|
37
|
+
static void
|
38
|
+
int_instream_adapter_mark(krypt_instream_adapter *adapter)
|
39
|
+
{
|
40
|
+
if (!adapter) return;
|
41
|
+
|
42
|
+
binyo_instream_mark(adapter->in);
|
43
|
+
}
|
44
|
+
|
45
|
+
static void
|
46
|
+
int_instream_adapter_free(krypt_instream_adapter *adapter)
|
47
|
+
{
|
48
|
+
if (!adapter) return;
|
49
|
+
|
50
|
+
binyo_instream_free(adapter->in);
|
51
|
+
xfree(adapter);
|
52
|
+
}
|
53
|
+
|
54
|
+
#define int_krypt_instream_adapter_set(klass, obj, adapter) \
|
55
|
+
do { \
|
56
|
+
if (!(adapter)) { \
|
57
|
+
rb_raise(eKryptError, "Uninitialized Adapter"); \
|
58
|
+
} \
|
59
|
+
(obj) = Data_Wrap_Struct((klass), int_instream_adapter_mark, int_instream_adapter_free, (adapter)); \
|
60
|
+
} while (0)
|
61
|
+
|
62
|
+
#define int_krypt_instream_adapter_get(obj, adapter) \
|
63
|
+
do { \
|
64
|
+
Data_Get_Struct((obj), krypt_instream_adapter, (adapter)); \
|
65
|
+
if (!(adapter)) { \
|
66
|
+
rb_raise(eKryptError, "Uninitialized Adapter"); \
|
67
|
+
} \
|
68
|
+
} while (0)
|
69
|
+
|
70
|
+
VALUE
|
71
|
+
krypt_instream_adapter_new(binyo_instream *in)
|
72
|
+
{
|
73
|
+
VALUE obj;
|
74
|
+
krypt_instream_adapter *adapter;
|
75
|
+
|
76
|
+
adapter = ALLOC(krypt_instream_adapter);
|
77
|
+
adapter->in = in;
|
78
|
+
int_krypt_instream_adapter_set(cKryptASN1Instream, obj, adapter);
|
79
|
+
return obj;
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* call-seq:
|
84
|
+
* in.read([len=nil], [buf=nil]) -> String or nil
|
85
|
+
*
|
86
|
+
* Please see IO#read for details.
|
87
|
+
*/
|
88
|
+
static VALUE
|
89
|
+
krypt_instream_adapter_read(int argc, VALUE *argv, VALUE self)
|
90
|
+
{
|
91
|
+
krypt_instream_adapter *adapter;
|
92
|
+
VALUE ret;
|
93
|
+
VALUE vlen = Qnil;
|
94
|
+
VALUE vbuf = Qnil;
|
95
|
+
|
96
|
+
rb_scan_args(argc, argv, "02", &vlen, &vbuf);
|
97
|
+
|
98
|
+
int_krypt_instream_adapter_get(self, adapter);
|
99
|
+
|
100
|
+
if (binyo_instream_rb_read(adapter->in, vlen, vbuf, &ret) == BINYO_ERR)
|
101
|
+
rb_raise(eKryptError, "Error reading stream");
|
102
|
+
return ret;
|
103
|
+
}
|
104
|
+
|
105
|
+
static int
|
106
|
+
int_whence_for(VALUE vwhence)
|
107
|
+
{
|
108
|
+
ID whence;
|
109
|
+
|
110
|
+
if (!SYMBOL_P(vwhence))
|
111
|
+
rb_raise(rb_eArgError, "whence must be a Symbol");
|
112
|
+
|
113
|
+
whence = SYM2ID(vwhence);
|
114
|
+
if (whence == sBinyo_ID_SEEK_CUR)
|
115
|
+
return SEEK_CUR;
|
116
|
+
else if (whence == sBinyo_ID_SEEK_SET)
|
117
|
+
return SEEK_SET;
|
118
|
+
else if (whence == sBinyo_ID_SEEK_END)
|
119
|
+
return SEEK_END;
|
120
|
+
else
|
121
|
+
rb_raise(eKryptASN1ParseError, "Unknown whence");
|
122
|
+
|
123
|
+
return Qnil; /* dummy */
|
124
|
+
}
|
125
|
+
|
126
|
+
/**
|
127
|
+
* call-seq:
|
128
|
+
* in.seek(n, [whence=:SEEK_SET]) -> 0
|
129
|
+
*
|
130
|
+
* Please see IO#seek for details.
|
131
|
+
*/
|
132
|
+
static VALUE
|
133
|
+
krypt_instream_adapter_seek(int argc, VALUE *argv, VALUE self)
|
134
|
+
{
|
135
|
+
VALUE n, vwhence = sBinyo_ID_SEEK_SET;
|
136
|
+
int whence;
|
137
|
+
krypt_instream_adapter *adapter;
|
138
|
+
|
139
|
+
rb_scan_args(argc, argv, "11", &n, &whence);
|
140
|
+
|
141
|
+
int_krypt_instream_adapter_get(self, adapter);
|
142
|
+
whence = int_whence_for(vwhence);
|
143
|
+
if (binyo_instream_seek(adapter->in, NUM2INT(n), whence) == BINYO_ERR)
|
144
|
+
rb_raise(eKryptASN1ParseError, "Seek failed");
|
145
|
+
|
146
|
+
return INT2FIX(0); /* same as rb_io_seek */
|
147
|
+
}
|
148
|
+
|
149
|
+
void
|
150
|
+
Init_krypt_instream_adapter(void)
|
151
|
+
{
|
152
|
+
#if 0
|
153
|
+
mKrypt = rb_define_module("Krypt");
|
154
|
+
mKryptASN1 = rb_define_module_under(mKrypt, "ASN1"); /* Let RDoc know */
|
155
|
+
#endif
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Document-class: Krypt::ASN1::Instream
|
159
|
+
*
|
160
|
+
* Acts as a drop-in replacement for an IO. It cannot be instantiated on
|
161
|
+
* its own, instances may be obtained by calling Header#value_io. Instream
|
162
|
+
* supports a reduced subset of the interface defined by IO.
|
163
|
+
*
|
164
|
+
* == Example usage
|
165
|
+
*
|
166
|
+
* === Reading the contents of an Instream
|
167
|
+
* der_io = # some IO representing a DER-encoded ASN.1 value
|
168
|
+
* parser = Krypt::ASN1::Parser.new
|
169
|
+
* token = parser.next(der_io)
|
170
|
+
* instream = token.value_io
|
171
|
+
* value = instream.read # contains the raw bytes of the token's value
|
172
|
+
*/
|
173
|
+
cKryptASN1Instream = rb_define_class_under(mKryptASN1, "Instream", rb_cObject);
|
174
|
+
rb_define_method(cKryptASN1Instream, "read", krypt_instream_adapter_read, -1);
|
175
|
+
rb_define_method(cKryptASN1Instream, "seek", krypt_instream_adapter_seek, -1);
|
176
|
+
rb_undef_method(CLASS_OF(cKryptASN1Instream), "new"); /* private constructor */
|
177
|
+
}
|
178
|
+
|
Binary file
|
@@ -0,0 +1,292 @@
|
|
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 "krypt_asn1-internal.h"
|
31
|
+
|
32
|
+
enum krypt_chunked_state {
|
33
|
+
NEW_HEADER = 0,
|
34
|
+
PROCESS_TAG,
|
35
|
+
PROCESS_LENGTH,
|
36
|
+
PROCESS_VALUE,
|
37
|
+
DONE
|
38
|
+
};
|
39
|
+
|
40
|
+
typedef struct krypt_instream_chunked {
|
41
|
+
binyo_instream_interface *methods;
|
42
|
+
binyo_instream *inner;
|
43
|
+
int values_only;
|
44
|
+
enum krypt_chunked_state state;
|
45
|
+
krypt_asn1_header *cur_header;
|
46
|
+
binyo_instream *cur_value_stream;
|
47
|
+
size_t header_offset;
|
48
|
+
} krypt_instream_chunked;
|
49
|
+
|
50
|
+
#define int_safe_cast(out, in) binyo_safe_cast_instream((out), (in), KRYPT_INSTREAM_TYPE_CHUNKED, krypt_instream_chunked)
|
51
|
+
|
52
|
+
static krypt_instream_chunked* int_chunked_alloc(void);
|
53
|
+
static ssize_t int_chunked_read(binyo_instream *in, uint8_t *buf, size_t len);
|
54
|
+
static int int_chunked_seek(binyo_instream *in, off_t offset, int whence);
|
55
|
+
static void int_chunked_mark(binyo_instream *in);
|
56
|
+
static void int_chunked_free(binyo_instream *in);
|
57
|
+
|
58
|
+
static binyo_instream_interface krypt_interface_chunked = {
|
59
|
+
KRYPT_INSTREAM_TYPE_CHUNKED,
|
60
|
+
int_chunked_read,
|
61
|
+
NULL,
|
62
|
+
NULL,
|
63
|
+
int_chunked_seek,
|
64
|
+
int_chunked_mark,
|
65
|
+
int_chunked_free
|
66
|
+
};
|
67
|
+
|
68
|
+
binyo_instream *
|
69
|
+
krypt_instream_new_chunked(binyo_instream *original, int values_only)
|
70
|
+
{
|
71
|
+
krypt_instream_chunked *in;
|
72
|
+
|
73
|
+
in = int_chunked_alloc();
|
74
|
+
in->inner = original;
|
75
|
+
in->values_only = values_only;
|
76
|
+
in->state = NEW_HEADER;
|
77
|
+
return (binyo_instream *) in;
|
78
|
+
}
|
79
|
+
|
80
|
+
static krypt_instream_chunked*
|
81
|
+
int_chunked_alloc(void)
|
82
|
+
{
|
83
|
+
krypt_instream_chunked *ret;
|
84
|
+
ret = ALLOC(krypt_instream_chunked);
|
85
|
+
memset(ret, 0, sizeof(krypt_instream_chunked));
|
86
|
+
ret->methods = &krypt_interface_chunked;
|
87
|
+
return ret;
|
88
|
+
}
|
89
|
+
|
90
|
+
static int
|
91
|
+
int_read_new_header(krypt_instream_chunked *in)
|
92
|
+
{
|
93
|
+
int ret;
|
94
|
+
krypt_asn1_header *next;
|
95
|
+
|
96
|
+
ret = krypt_asn1_next_header(in->inner, &next);
|
97
|
+
if (ret == KRYPT_ASN1_EOF) {
|
98
|
+
krypt_error_add("Premature end of value detected");
|
99
|
+
return BINYO_ERR;
|
100
|
+
}
|
101
|
+
if (ret == KRYPT_ERR) {
|
102
|
+
krypt_error_add("An error occured while reading the ASN.1 header");
|
103
|
+
return BINYO_ERR;
|
104
|
+
}
|
105
|
+
|
106
|
+
if (in->cur_header)
|
107
|
+
krypt_asn1_header_free(in->cur_header);
|
108
|
+
in->cur_header = next;
|
109
|
+
in->state = PROCESS_TAG;
|
110
|
+
in->header_offset = 0;
|
111
|
+
return BINYO_OK;
|
112
|
+
}
|
113
|
+
|
114
|
+
static size_t
|
115
|
+
int_read_header_bytes(krypt_instream_chunked *in,
|
116
|
+
uint8_t * bytes,
|
117
|
+
size_t bytes_len,
|
118
|
+
enum krypt_chunked_state next_state,
|
119
|
+
uint8_t *buf,
|
120
|
+
size_t len)
|
121
|
+
{
|
122
|
+
size_t to_read;
|
123
|
+
size_t available = bytes_len - in->header_offset;
|
124
|
+
|
125
|
+
if (len < available) {
|
126
|
+
in->header_offset += len;
|
127
|
+
to_read = len;
|
128
|
+
}
|
129
|
+
else {
|
130
|
+
in->state = next_state;
|
131
|
+
in->header_offset = 0;
|
132
|
+
to_read = available;
|
133
|
+
}
|
134
|
+
|
135
|
+
memcpy(buf, bytes, to_read);
|
136
|
+
return to_read;
|
137
|
+
}
|
138
|
+
|
139
|
+
static ssize_t
|
140
|
+
int_read_value(krypt_instream_chunked *in, uint8_t *buf, size_t len)
|
141
|
+
{
|
142
|
+
ssize_t read;
|
143
|
+
|
144
|
+
if (!in->cur_value_stream)
|
145
|
+
in->cur_value_stream = krypt_asn1_get_value_stream(in->inner, in->cur_header, in->values_only);
|
146
|
+
|
147
|
+
read = binyo_instream_read(in->cur_value_stream, buf, len);
|
148
|
+
if (read == BINYO_ERR) return BINYO_ERR;
|
149
|
+
|
150
|
+
if (read == BINYO_IO_EOF) {
|
151
|
+
if (in->state != DONE)
|
152
|
+
in->state = NEW_HEADER;
|
153
|
+
binyo_instream_free(in->cur_value_stream);
|
154
|
+
in->cur_value_stream = NULL;
|
155
|
+
read = 0;
|
156
|
+
}
|
157
|
+
|
158
|
+
return read;
|
159
|
+
}
|
160
|
+
|
161
|
+
/* If state is PROCESS_VALUE, this means that the tag bytes
|
162
|
+
* have been consumed. As an EOC contains no value, we are
|
163
|
+
* done.
|
164
|
+
*/
|
165
|
+
#define int_check_done(in) \
|
166
|
+
do { \
|
167
|
+
if ((in)->cur_header->tag == TAGS_END_OF_CONTENTS && \
|
168
|
+
(in)->cur_header->tag_class == TAG_CLASS_UNIVERSAL && \
|
169
|
+
(in)->state == PROCESS_VALUE) { \
|
170
|
+
(in)->state = DONE; \
|
171
|
+
} \
|
172
|
+
} while (0)
|
173
|
+
|
174
|
+
/* TODO: check overflow */
|
175
|
+
static ssize_t
|
176
|
+
int_read_single_element(krypt_instream_chunked *in, uint8_t *buf, size_t len)
|
177
|
+
{
|
178
|
+
ssize_t read = 0;
|
179
|
+
size_t total = 0;
|
180
|
+
|
181
|
+
#define add_header_bytes() \
|
182
|
+
do { \
|
183
|
+
if (!in->values_only) { \
|
184
|
+
total += read; \
|
185
|
+
if (total == len || in->state == DONE) \
|
186
|
+
return (ssize_t) total; \
|
187
|
+
if (total > len) return BINYO_ERR; \
|
188
|
+
buf += read; \
|
189
|
+
} \
|
190
|
+
} while (0)
|
191
|
+
|
192
|
+
switch (in->state) {
|
193
|
+
case NEW_HEADER:
|
194
|
+
if (!int_read_new_header(in))
|
195
|
+
return BINYO_ERR;
|
196
|
+
/* fallthrough */
|
197
|
+
case PROCESS_TAG:
|
198
|
+
read = int_read_header_bytes(in,
|
199
|
+
in->cur_header->tag_bytes,
|
200
|
+
in->cur_header->tag_len,
|
201
|
+
PROCESS_LENGTH,
|
202
|
+
buf,
|
203
|
+
len);
|
204
|
+
add_header_bytes();
|
205
|
+
/* fallthrough */
|
206
|
+
case PROCESS_LENGTH:
|
207
|
+
read = int_read_header_bytes(in,
|
208
|
+
in->cur_header->length_bytes,
|
209
|
+
in->cur_header->length_len,
|
210
|
+
PROCESS_VALUE,
|
211
|
+
buf,
|
212
|
+
len);
|
213
|
+
int_check_done(in);
|
214
|
+
add_header_bytes();
|
215
|
+
/* fallthrough */
|
216
|
+
case PROCESS_VALUE:
|
217
|
+
read = int_read_value(in, buf, len);
|
218
|
+
if (read == BINYO_ERR) return BINYO_ERR;
|
219
|
+
total += read;
|
220
|
+
buf += read;
|
221
|
+
return (ssize_t) total;
|
222
|
+
default:
|
223
|
+
krypt_error_add("Internal error");
|
224
|
+
return BINYO_ERR; /* dummy */
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
static ssize_t
|
229
|
+
int_read(krypt_instream_chunked *in, uint8_t *buf, size_t len)
|
230
|
+
{
|
231
|
+
ssize_t read = 0;
|
232
|
+
size_t total = 0;
|
233
|
+
|
234
|
+
while (total != len && in->state != DONE) {
|
235
|
+
read = int_read_single_element(in, buf, len);
|
236
|
+
if (read == BINYO_ERR) return BINYO_ERR;
|
237
|
+
if (total > (size_t) (SSIZE_MAX - read)) {
|
238
|
+
krypt_error_add("Stream too large");
|
239
|
+
return BINYO_ERR;
|
240
|
+
}
|
241
|
+
total += read;
|
242
|
+
buf += read;
|
243
|
+
}
|
244
|
+
return total;
|
245
|
+
}
|
246
|
+
|
247
|
+
static ssize_t
|
248
|
+
int_chunked_read(binyo_instream *instream, uint8_t *buf, size_t len)
|
249
|
+
{
|
250
|
+
krypt_instream_chunked *in;
|
251
|
+
|
252
|
+
int_safe_cast(in, instream);
|
253
|
+
|
254
|
+
if (!buf) return BINYO_ERR;
|
255
|
+
if (in->state == DONE)
|
256
|
+
return BINYO_IO_EOF;
|
257
|
+
|
258
|
+
return int_read(in, buf, len);
|
259
|
+
}
|
260
|
+
|
261
|
+
static int
|
262
|
+
int_chunked_seek(binyo_instream *instream, off_t offset, int whence)
|
263
|
+
{
|
264
|
+
/* int_instream_chunked *in;
|
265
|
+
|
266
|
+
int_safe_cast(in, instream); */
|
267
|
+
|
268
|
+
return BINYO_OK;
|
269
|
+
/* TODO */
|
270
|
+
}
|
271
|
+
|
272
|
+
static void
|
273
|
+
int_chunked_mark(binyo_instream *instream)
|
274
|
+
{
|
275
|
+
krypt_instream_chunked *in;
|
276
|
+
|
277
|
+
if (!instream) return;
|
278
|
+
int_safe_cast(in, instream);
|
279
|
+
binyo_instream_mark(in->inner);
|
280
|
+
}
|
281
|
+
|
282
|
+
static void
|
283
|
+
int_chunked_free(binyo_instream *instream)
|
284
|
+
{
|
285
|
+
krypt_instream_chunked *in;
|
286
|
+
|
287
|
+
if (!instream) return;
|
288
|
+
int_safe_cast(in, instream);
|
289
|
+
if (in->cur_header)
|
290
|
+
krypt_asn1_header_free(in->cur_header);
|
291
|
+
}
|
292
|
+
|
Binary file
|
@@ -0,0 +1,156 @@
|
|
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
|
+
typedef struct krypt_instream_definite_st {
|
32
|
+
binyo_instream_interface *methods;
|
33
|
+
binyo_instream *inner;
|
34
|
+
size_t max_read;
|
35
|
+
size_t num_read;
|
36
|
+
} krypt_instream_definite;
|
37
|
+
|
38
|
+
#define int_safe_cast(out, in) binyo_safe_cast_instream((out), (in), KRYPT_INSTREAM_TYPE_DEFINITE, krypt_instream_definite)
|
39
|
+
|
40
|
+
static krypt_instream_definite* int_definite_alloc(void);
|
41
|
+
static ssize_t int_definite_read(binyo_instream *in, uint8_t *buf, size_t len);
|
42
|
+
static int int_definite_seek(binyo_instream *in, off_t offset, int whence);
|
43
|
+
static void int_definite_mark(binyo_instream *in);
|
44
|
+
static void int_definite_free(binyo_instream *in);
|
45
|
+
|
46
|
+
static binyo_instream_interface krypt_interface_definite = {
|
47
|
+
KRYPT_INSTREAM_TYPE_DEFINITE,
|
48
|
+
int_definite_read,
|
49
|
+
NULL,
|
50
|
+
NULL,
|
51
|
+
int_definite_seek,
|
52
|
+
int_definite_mark,
|
53
|
+
int_definite_free
|
54
|
+
};
|
55
|
+
|
56
|
+
binyo_instream *
|
57
|
+
krypt_instream_new_definite(binyo_instream *original, size_t len)
|
58
|
+
{
|
59
|
+
krypt_instream_definite *in;
|
60
|
+
|
61
|
+
in = int_definite_alloc();
|
62
|
+
in->inner = original;
|
63
|
+
in->max_read = len;
|
64
|
+
return (binyo_instream *) in;
|
65
|
+
}
|
66
|
+
|
67
|
+
static krypt_instream_definite*
|
68
|
+
int_definite_alloc(void)
|
69
|
+
{
|
70
|
+
krypt_instream_definite *ret;
|
71
|
+
ret = ALLOC(krypt_instream_definite);
|
72
|
+
memset(ret, 0, sizeof(krypt_instream_definite));
|
73
|
+
ret->methods = &krypt_interface_definite;
|
74
|
+
return ret;
|
75
|
+
}
|
76
|
+
|
77
|
+
static ssize_t
|
78
|
+
int_definite_read(binyo_instream *instream, uint8_t *buf, size_t len)
|
79
|
+
{
|
80
|
+
krypt_instream_definite *in;
|
81
|
+
size_t to_read;
|
82
|
+
ssize_t r;
|
83
|
+
|
84
|
+
int_safe_cast(in, instream);
|
85
|
+
|
86
|
+
if (!buf) return BINYO_ERR;
|
87
|
+
|
88
|
+
if (in->num_read == in->max_read)
|
89
|
+
return BINYO_IO_EOF;
|
90
|
+
|
91
|
+
if (in->max_read - in->num_read < len)
|
92
|
+
to_read = in->max_read - in->num_read;
|
93
|
+
else
|
94
|
+
to_read = len;
|
95
|
+
|
96
|
+
r = binyo_instream_read(in->inner, buf, to_read);
|
97
|
+
if (r == BINYO_ERR || r == BINYO_IO_EOF) return BINYO_ERR;
|
98
|
+
if (in->num_read >= SIZE_MAX - r) {
|
99
|
+
krypt_error_add("Stream too large");
|
100
|
+
return BINYO_ERR;
|
101
|
+
}
|
102
|
+
|
103
|
+
in->num_read += r;
|
104
|
+
return r;
|
105
|
+
}
|
106
|
+
|
107
|
+
static int
|
108
|
+
int_definite_seek(binyo_instream *instream, off_t offset, int whence)
|
109
|
+
{
|
110
|
+
off_t real_off;
|
111
|
+
long numread;
|
112
|
+
krypt_instream_definite *in;
|
113
|
+
|
114
|
+
int_safe_cast(in, instream);
|
115
|
+
|
116
|
+
switch (whence) {
|
117
|
+
case SEEK_CUR:
|
118
|
+
real_off = offset;
|
119
|
+
break;
|
120
|
+
case SEEK_SET:
|
121
|
+
real_off = offset - in->num_read;
|
122
|
+
break;
|
123
|
+
case SEEK_END:
|
124
|
+
real_off = offset + in->max_read - in->num_read;
|
125
|
+
break;
|
126
|
+
default:
|
127
|
+
krypt_error_add("Unknown whence: %d", whence);
|
128
|
+
return BINYO_ERR;
|
129
|
+
}
|
130
|
+
|
131
|
+
numread = in->num_read;
|
132
|
+
if (numread + real_off < 0 || numread + real_off >= (long)in->max_read) {
|
133
|
+
krypt_error_add("Invalid seek position: %ld", numread + real_off);
|
134
|
+
return BINYO_ERR;
|
135
|
+
}
|
136
|
+
|
137
|
+
return binyo_instream_seek(in->inner, offset, whence);
|
138
|
+
}
|
139
|
+
|
140
|
+
static void
|
141
|
+
int_definite_mark(binyo_instream *instream)
|
142
|
+
{
|
143
|
+
krypt_instream_definite *in;
|
144
|
+
|
145
|
+
if (!instream) return;
|
146
|
+
int_safe_cast(in, instream);
|
147
|
+
binyo_instream_mark(in->inner);
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
static void
|
152
|
+
int_definite_free(binyo_instream *instream)
|
153
|
+
{
|
154
|
+
/* do not free the inner stream */
|
155
|
+
}
|
156
|
+
|
Binary file
|