krypt-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/ext/krypt/core/Makefile +221 -0
- data/ext/krypt/core/binyo-error.h +40 -0
- data/ext/krypt/core/binyo-io-buffer.h +54 -0
- data/ext/krypt/core/binyo-io.h +131 -0
- data/ext/krypt/core/extconf.h +8 -0
- data/ext/krypt/core/extconf.rb +80 -0
- data/ext/krypt/core/krypt-core.c +110 -0
- data/ext/krypt/core/krypt-core.h +97 -0
- data/ext/krypt/core/krypt-core.o +0 -0
- data/ext/krypt/core/krypt-provider.h +86 -0
- data/ext/krypt/core/krypt_asn1-internal.c +681 -0
- data/ext/krypt/core/krypt_asn1-internal.h +117 -0
- data/ext/krypt/core/krypt_asn1-internal.o +0 -0
- data/ext/krypt/core/krypt_asn1.c +2109 -0
- data/ext/krypt/core/krypt_asn1.h +88 -0
- data/ext/krypt/core/krypt_asn1.o +0 -0
- data/ext/krypt/core/krypt_asn1_codec.c +973 -0
- data/ext/krypt/core/krypt_asn1_codec.o +0 -0
- data/ext/krypt/core/krypt_asn1_in_adapter.c +178 -0
- data/ext/krypt/core/krypt_asn1_in_adapter.o +0 -0
- data/ext/krypt/core/krypt_asn1_in_chunked.c +292 -0
- data/ext/krypt/core/krypt_asn1_in_chunked.o +0 -0
- data/ext/krypt/core/krypt_asn1_in_definite.c +156 -0
- data/ext/krypt/core/krypt_asn1_in_definite.o +0 -0
- data/ext/krypt/core/krypt_asn1_parser.c +592 -0
- data/ext/krypt/core/krypt_asn1_parser.o +0 -0
- data/ext/krypt/core/krypt_asn1_template-internal.h +185 -0
- data/ext/krypt/core/krypt_asn1_template.c +459 -0
- data/ext/krypt/core/krypt_asn1_template.h +56 -0
- data/ext/krypt/core/krypt_asn1_template.o +0 -0
- data/ext/krypt/core/krypt_asn1_template_encoder.c +76 -0
- data/ext/krypt/core/krypt_asn1_template_encoder.o +0 -0
- data/ext/krypt/core/krypt_asn1_template_parser.c +1176 -0
- data/ext/krypt/core/krypt_asn1_template_parser.o +0 -0
- data/ext/krypt/core/krypt_b64-internal.h +38 -0
- data/ext/krypt/core/krypt_b64.c +391 -0
- data/ext/krypt/core/krypt_b64.h +41 -0
- data/ext/krypt/core/krypt_b64.o +0 -0
- data/ext/krypt/core/krypt_digest.c +391 -0
- data/ext/krypt/core/krypt_digest.h +51 -0
- data/ext/krypt/core/krypt_digest.o +0 -0
- data/ext/krypt/core/krypt_error.c +221 -0
- data/ext/krypt/core/krypt_error.h +46 -0
- data/ext/krypt/core/krypt_error.o +0 -0
- data/ext/krypt/core/krypt_hex-internal.h +36 -0
- data/ext/krypt/core/krypt_hex.c +255 -0
- data/ext/krypt/core/krypt_hex.h +41 -0
- data/ext/krypt/core/krypt_hex.o +0 -0
- data/ext/krypt/core/krypt_io.c +65 -0
- data/ext/krypt/core/krypt_io.h +56 -0
- data/ext/krypt/core/krypt_io.o +0 -0
- data/ext/krypt/core/krypt_io_in_pem.c +397 -0
- data/ext/krypt/core/krypt_io_in_pem.o +0 -0
- data/ext/krypt/core/krypt_missing.c +238 -0
- data/ext/krypt/core/krypt_missing.h +62 -0
- data/ext/krypt/core/krypt_missing.o +0 -0
- data/ext/krypt/core/krypt_pem.c +171 -0
- data/ext/krypt/core/krypt_pem.o +0 -0
- data/ext/krypt/core/krypt_provider-internal.h +40 -0
- data/ext/krypt/core/krypt_provider.c +136 -0
- data/ext/krypt/core/krypt_provider.o +0 -0
- data/ext/krypt/core/kryptcore.so +0 -0
- data/ext/krypt/core/mkmf.log +130 -0
- data/lib/krypt-core/version.rb +3 -0
- data/lib/krypt-core.rb +35 -0
- data/lib/kryptcore.so +0 -0
- data/spec/README +2 -0
- data/test/README +2 -0
- data/test/res/certificate.cer +0 -0
- data/test/resources.rb +48 -0
- data/test/scratch.rb +17 -0
- metadata +150 -0
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
|