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
@@ -0,0 +1,185 @@
|
|
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
|
+
#if !defined(_KRYPT_ASN1_TEMPLATE_INTERNAL_H_)
|
30
|
+
#define _KRYPT_ASN1_TEMPLATE_INTERNAL_H_
|
31
|
+
|
32
|
+
extern ID sKrypt_ID_OPTIONS, sKrypt_ID_NAME, sKrypt_ID_TYPE,
|
33
|
+
sKrypt_ID_CODEC, sKrypt_ID_LAYOUT, sKrypt_ID_MIN_SIZE;
|
34
|
+
|
35
|
+
extern ID sKrypt_ID_DEFAULT, sKrypt_ID_OPTIONAL, sKrypt_ID_TAG, sKrypt_ID_TAGGING;
|
36
|
+
|
37
|
+
extern ID sKrypt_ID_PRIMITIVE, sKrypt_ID_SEQUENCE, sKrypt_ID_SET, sKrypt_ID_TEMPLATE,
|
38
|
+
sKrypt_ID_SEQUENCE_OF, sKrypt_ID_SET_OF, sKrypt_ID_CHOICE, sKrypt_ID_ANY;
|
39
|
+
|
40
|
+
extern ID sKrypt_IV_VALUE, sKrypt_IV_TYPE, sKrypt_IV_DEFINITION, sKrypt_IV_OPTIONS;
|
41
|
+
|
42
|
+
extern ID sKrypt_ID_MERGE;
|
43
|
+
|
44
|
+
extern VALUE cKryptASN1TemplateValue;
|
45
|
+
|
46
|
+
#define KRYPT_TEMPLATE_PARSED (1 << 0)
|
47
|
+
#define KRYPT_TEMPLATE_DECODED (1 << 1)
|
48
|
+
#define KRYPT_TEMPLATE_MODIFIED (1 << 2)
|
49
|
+
|
50
|
+
typedef struct krypt_asn1_template_st {
|
51
|
+
int flags;
|
52
|
+
krypt_asn1_object *object;
|
53
|
+
VALUE definition;
|
54
|
+
VALUE options;
|
55
|
+
VALUE value;
|
56
|
+
} krypt_asn1_template;
|
57
|
+
|
58
|
+
krypt_asn1_template *krypt_asn1_template_new(krypt_asn1_object *object, VALUE definition, VALUE options);
|
59
|
+
krypt_asn1_template *krypt_asn1_template_new_from_stream(binyo_instream *in, krypt_asn1_header *header, VALUE definition, VALUE options);
|
60
|
+
krypt_asn1_template *krypt_asn1_template_new_value(VALUE value);
|
61
|
+
|
62
|
+
void krypt_asn1_template_mark(krypt_asn1_template *t);
|
63
|
+
void krypt_asn1_template_free(krypt_asn1_template *t);
|
64
|
+
|
65
|
+
#define krypt_asn1_template_set(klass, obj, t) \
|
66
|
+
do { \
|
67
|
+
if (!(t)) { \
|
68
|
+
rb_raise(eKryptError, "Uninitialized krypt_asn1_template"); \
|
69
|
+
} \
|
70
|
+
(obj) = Data_Wrap_Struct((klass), krypt_asn1_template_mark, krypt_asn1_template_free, (t)); \
|
71
|
+
} while (0)
|
72
|
+
|
73
|
+
#define krypt_asn1_template_get(obj, t) \
|
74
|
+
do { \
|
75
|
+
Data_Get_Struct((obj), krypt_asn1_template, (t)); \
|
76
|
+
if (!(t)) { \
|
77
|
+
rb_raise(eKryptError, "Uninitialized krypt_asn1_template"); \
|
78
|
+
} \
|
79
|
+
} while (0)
|
80
|
+
|
81
|
+
#define krypt_asn1_template_get_definition(o) ((o)->definition)
|
82
|
+
#define krypt_asn1_template_set_definition(o, v) ((o)->definition = (v))
|
83
|
+
#define krypt_asn1_template_get_options(o) ((o)->options)
|
84
|
+
#define krypt_asn1_template_set_options(o, v) ((o)->options = (v))
|
85
|
+
#define krypt_asn1_template_get_object(o) ((o)->object)
|
86
|
+
#define krypt_asn1_template_set_object(o, v) ((o)->object = (v))
|
87
|
+
#define krypt_asn1_template_get_value(o) ((o)->value)
|
88
|
+
#define krypt_asn1_template_set_value(o, v) ((o)->value = (v))
|
89
|
+
#define krypt_asn1_template_is_parsed(o) (((o)->flags & KRYPT_TEMPLATE_PARSED) == KRYPT_TEMPLATE_PARSED)
|
90
|
+
#define krypt_asn1_template_is_decoded(o) (((o)->flags & KRYPT_TEMPLATE_DECODED) == KRYPT_TEMPLATE_DECODED)
|
91
|
+
#define krypt_asn1_template_is_modified(o) (((o)->flags & KRYPT_TEMPLATE_MODIFIED) == KRYPT_TEMPLATE_MODIFIED)
|
92
|
+
#define krypt_asn1_template_set_parsed(o, b) \
|
93
|
+
do { \
|
94
|
+
if (b) { \
|
95
|
+
(o)->flags |= KRYPT_TEMPLATE_PARSED; \
|
96
|
+
} else { \
|
97
|
+
(o)->flags &= ~KRYPT_TEMPLATE_PARSED; \
|
98
|
+
} \
|
99
|
+
} while (0)
|
100
|
+
#define krypt_asn1_template_set_decoded(o, b) \
|
101
|
+
do { \
|
102
|
+
if (b) { \
|
103
|
+
(o)->flags |= KRYPT_TEMPLATE_DECODED; \
|
104
|
+
} else { \
|
105
|
+
(o)->flags &= ~KRYPT_TEMPLATE_DECODED; \
|
106
|
+
} \
|
107
|
+
} while (0)
|
108
|
+
#define krypt_asn1_template_set_modified(o, b) \
|
109
|
+
do { \
|
110
|
+
if (b) { \
|
111
|
+
(o)->flags |= KRYPT_TEMPLATE_MODIFIED; \
|
112
|
+
} else { \
|
113
|
+
(o)->flags &= ~KRYPT_TEMPLATE_MODIFIED; \
|
114
|
+
} \
|
115
|
+
} while (0)
|
116
|
+
|
117
|
+
#define krypt_definition_get(o) rb_ivar_get((o), sKrypt_IV_DEFINITION)
|
118
|
+
|
119
|
+
#define krypt_hash_get_codec(d) rb_hash_aref((d), ID2SYM(sKrypt_ID_CODEC))
|
120
|
+
#define krypt_hash_get_options(o) rb_hash_aref((o), ID2SYM(sKrypt_ID_OPTIONS))
|
121
|
+
#define krypt_hash_get_default_value(o) rb_hash_aref((o), ID2SYM(sKrypt_ID_DEFAULT))
|
122
|
+
#define krypt_hash_get_name(d) rb_hash_aref((d), ID2SYM(sKrypt_ID_NAME))
|
123
|
+
#define krypt_hash_get_type(d) rb_hash_aref((d), ID2SYM(sKrypt_ID_TYPE))
|
124
|
+
#define krypt_hash_get_optional(d) rb_hash_aref((d), ID2SYM(sKrypt_ID_OPTIONAL))
|
125
|
+
#define krypt_hash_get_tag(d) rb_hash_aref((d), ID2SYM(sKrypt_ID_TAG))
|
126
|
+
#define krypt_hash_get_tagging(d) rb_hash_aref((d), ID2SYM(sKrypt_ID_TAGGING))
|
127
|
+
#define krypt_hash_get_layout(d) rb_hash_aref((d), ID2SYM(sKrypt_ID_LAYOUT))
|
128
|
+
#define krypt_hash_get_min_size(d) rb_hash_aref((d), ID2SYM(sKrypt_ID_MIN_SIZE))
|
129
|
+
|
130
|
+
typedef struct krypt_asn1_definition_st {
|
131
|
+
VALUE definition;
|
132
|
+
VALUE options;
|
133
|
+
VALUE values[8];
|
134
|
+
unsigned short value_read[8];
|
135
|
+
long matched_layout; /* this information is only used by CHOICEs */
|
136
|
+
} krypt_asn1_definition;
|
137
|
+
|
138
|
+
#define KRYPT_DEFINITION_NAME 0
|
139
|
+
#define KRYPT_DEFINITION_TYPE 1
|
140
|
+
#define KRYPT_DEFINITION_LAYOUT 2
|
141
|
+
#define KRYPT_DEFINITION_MIN_SIZE 3
|
142
|
+
#define KRYPT_DEFINITION_OPTIONAL 4
|
143
|
+
#define KRYPT_DEFINITION_TAG 5
|
144
|
+
#define KRYPT_DEFINITION_TAGGING 6
|
145
|
+
#define KRYPT_DEFINITION_DEFAULT 7
|
146
|
+
|
147
|
+
void krypt_definition_init(krypt_asn1_definition *def, VALUE definition, VALUE options);
|
148
|
+
|
149
|
+
#define get_or_raise(dest, v, msg) \
|
150
|
+
do { \
|
151
|
+
VALUE value = (v); \
|
152
|
+
if (NIL_P(value)) { \
|
153
|
+
krypt_error_add((msg)); \
|
154
|
+
return 0; \
|
155
|
+
} \
|
156
|
+
(dest) = value; \
|
157
|
+
} while (0)
|
158
|
+
|
159
|
+
#define krypt_definition_get_definition(def) ((def)->definition)
|
160
|
+
#define krypt_definition_set_definition(def, d) ((def)->definition = (d))
|
161
|
+
#define krypt_definition_get_options(def) ((def)->options)
|
162
|
+
#define krypt_definition_set_options(def, o) ((def)->options = (o))
|
163
|
+
#define krypt_definition_get_matched_layout(def) ((def)->matched_layout)
|
164
|
+
#define krypt_definition_set_matched_layout(def, i) ((def)->matched_layout = (i))
|
165
|
+
|
166
|
+
VALUE krypt_definition_get_name(krypt_asn1_definition *def);
|
167
|
+
VALUE krypt_definition_get_type(krypt_asn1_definition *def);
|
168
|
+
VALUE krypt_definition_get_layout(krypt_asn1_definition *def);
|
169
|
+
VALUE krypt_definition_get_min_size(krypt_asn1_definition *def);
|
170
|
+
VALUE krypt_definition_get_optional(krypt_asn1_definition *def);
|
171
|
+
VALUE krypt_definition_get_tag(krypt_asn1_definition *def);
|
172
|
+
VALUE krypt_definition_get_tagging(krypt_asn1_definition *def);
|
173
|
+
VALUE krypt_definition_get_default_value(krypt_asn1_definition *def);
|
174
|
+
int krypt_definition_is_optional(krypt_asn1_definition *def);
|
175
|
+
int krypt_definition_has_default(krypt_asn1_definition *def);
|
176
|
+
|
177
|
+
int krypt_asn1_template_error_add(VALUE definition);
|
178
|
+
int krypt_asn1_template_get_cb_value(VALUE self, ID ivname, VALUE *out);
|
179
|
+
void krypt_asn1_template_set_cb_value(VALUE self, ID ivname, VALUE value);
|
180
|
+
int krypt_asn1_template_encode(VALUE templ, VALUE *out);
|
181
|
+
|
182
|
+
void Init_krypt_asn1_template_parser(void);
|
183
|
+
|
184
|
+
#endif /*_KRYPT_ASN1_TEMPLATE_INTERNAL_H_ */
|
185
|
+
|
@@ -0,0 +1,459 @@
|
|
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
|
+
#include "krypt_asn1_template-internal.h"
|
32
|
+
|
33
|
+
ID sKrypt_ID_OPTIONS, sKrypt_ID_NAME, sKrypt_ID_TYPE,
|
34
|
+
sKrypt_ID_CODEC, sKrypt_ID_LAYOUT, sKrypt_ID_MIN_SIZE;
|
35
|
+
|
36
|
+
ID sKrypt_ID_DEFAULT, sKrypt_ID_OPTIONAL, sKrypt_ID_TAG, sKrypt_ID_TAGGING;
|
37
|
+
|
38
|
+
ID sKrypt_ID_PRIMITIVE, sKrypt_ID_SEQUENCE, sKrypt_ID_SET, sKrypt_ID_TEMPLATE,
|
39
|
+
sKrypt_ID_SEQUENCE_OF, sKrypt_ID_SET_OF, sKrypt_ID_CHOICE, sKrypt_ID_ANY;
|
40
|
+
|
41
|
+
ID sKrypt_IV_TYPE, sKrypt_IV_DEFINITION, sKrypt_IV_OPTIONS;
|
42
|
+
|
43
|
+
ID sKrypt_ID_MERGE;
|
44
|
+
|
45
|
+
VALUE mKryptASN1Template;
|
46
|
+
VALUE cKryptASN1TemplateValue;
|
47
|
+
|
48
|
+
void
|
49
|
+
krypt_definition_init(krypt_asn1_definition *def, VALUE definition, VALUE options)
|
50
|
+
{
|
51
|
+
memset(def, 0, sizeof(krypt_asn1_definition));
|
52
|
+
def->definition = definition;
|
53
|
+
def->options = options;
|
54
|
+
}
|
55
|
+
|
56
|
+
#define DEFINITION_GETTER(getter, idx) \
|
57
|
+
VALUE \
|
58
|
+
krypt_definition_get_##getter(krypt_asn1_definition *def) \
|
59
|
+
{ \
|
60
|
+
if (!def->value_read[(idx)]) { \
|
61
|
+
def->values[(idx)] = krypt_hash_get_##getter(def->definition); \
|
62
|
+
def->value_read[(idx)] = 1; \
|
63
|
+
} \
|
64
|
+
return def->values[(idx)]; \
|
65
|
+
}
|
66
|
+
|
67
|
+
#define OPTIONS_GETTER(getter, idx) \
|
68
|
+
VALUE \
|
69
|
+
krypt_definition_get_##getter(krypt_asn1_definition *def) \
|
70
|
+
{ \
|
71
|
+
if (!def->value_read[(idx)]) { \
|
72
|
+
if (NIL_P(def->options)) \
|
73
|
+
def->values[(idx)] = Qnil; \
|
74
|
+
else \
|
75
|
+
def->values[(idx)] = krypt_hash_get_##getter(def->options); \
|
76
|
+
def->value_read[(idx)] = 1; \
|
77
|
+
} \
|
78
|
+
return def->values[(idx)]; \
|
79
|
+
}
|
80
|
+
|
81
|
+
DEFINITION_GETTER(name, KRYPT_DEFINITION_NAME)
|
82
|
+
DEFINITION_GETTER(type, KRYPT_DEFINITION_TYPE)
|
83
|
+
DEFINITION_GETTER(layout, KRYPT_DEFINITION_LAYOUT)
|
84
|
+
DEFINITION_GETTER(min_size, KRYPT_DEFINITION_MIN_SIZE)
|
85
|
+
|
86
|
+
OPTIONS_GETTER(optional, KRYPT_DEFINITION_OPTIONAL)
|
87
|
+
OPTIONS_GETTER(tag, KRYPT_DEFINITION_TAG)
|
88
|
+
OPTIONS_GETTER(tagging, KRYPT_DEFINITION_TAGGING)
|
89
|
+
OPTIONS_GETTER(default_value, KRYPT_DEFINITION_DEFAULT)
|
90
|
+
|
91
|
+
int
|
92
|
+
krypt_definition_is_optional(krypt_asn1_definition *def)
|
93
|
+
{
|
94
|
+
VALUE x = krypt_definition_get_optional(def);
|
95
|
+
int optional = RTEST(x);
|
96
|
+
if (optional) return 1;
|
97
|
+
x = krypt_definition_get_default_value(def);
|
98
|
+
return !NIL_P(x);
|
99
|
+
}
|
100
|
+
|
101
|
+
int
|
102
|
+
krypt_definition_has_default(krypt_asn1_definition *def)
|
103
|
+
{
|
104
|
+
return !NIL_P(krypt_definition_get_default_value(def));
|
105
|
+
}
|
106
|
+
|
107
|
+
krypt_asn1_template *
|
108
|
+
krypt_asn1_template_new(krypt_asn1_object *object, VALUE definition, VALUE options)
|
109
|
+
{
|
110
|
+
krypt_asn1_template *ret;
|
111
|
+
|
112
|
+
ret = ALLOC(krypt_asn1_template);
|
113
|
+
ret->object = object;
|
114
|
+
ret->definition = definition;
|
115
|
+
ret->options = options;
|
116
|
+
ret->value = Qnil;
|
117
|
+
ret->flags = 0;
|
118
|
+
return ret;
|
119
|
+
}
|
120
|
+
|
121
|
+
krypt_asn1_template *
|
122
|
+
krypt_asn1_template_new_from_stream(binyo_instream *in, krypt_asn1_header *header, VALUE definition, VALUE options)
|
123
|
+
{
|
124
|
+
krypt_asn1_object *encoding;
|
125
|
+
uint8_t *value = NULL;
|
126
|
+
size_t value_len;
|
127
|
+
|
128
|
+
if (krypt_asn1_get_value(in, header, &value, &value_len) == KRYPT_ERR) return NULL;
|
129
|
+
if (!(encoding = krypt_asn1_object_new_value(header, value, value_len))) return NULL;
|
130
|
+
return krypt_asn1_template_new(encoding, definition, options);
|
131
|
+
}
|
132
|
+
|
133
|
+
krypt_asn1_template *
|
134
|
+
krypt_asn1_template_new_value(VALUE value)
|
135
|
+
{
|
136
|
+
krypt_asn1_template *ret;
|
137
|
+
|
138
|
+
ret = krypt_asn1_template_new(NULL, Qnil, Qnil);
|
139
|
+
ret->value = value;
|
140
|
+
ret->flags = KRYPT_TEMPLATE_PARSED | KRYPT_TEMPLATE_DECODED;
|
141
|
+
return ret;
|
142
|
+
}
|
143
|
+
|
144
|
+
void
|
145
|
+
krypt_asn1_template_free(krypt_asn1_template *template)
|
146
|
+
{
|
147
|
+
if (!template) return;
|
148
|
+
if (template->object)
|
149
|
+
krypt_asn1_object_free(template->object);
|
150
|
+
xfree(template);
|
151
|
+
}
|
152
|
+
|
153
|
+
void
|
154
|
+
krypt_asn1_template_mark(krypt_asn1_template *template)
|
155
|
+
{
|
156
|
+
if (!template) return;
|
157
|
+
if (!NIL_P(template->value))
|
158
|
+
rb_gc_mark(template->value);
|
159
|
+
}
|
160
|
+
|
161
|
+
static VALUE
|
162
|
+
krypt_asn1_template_initialize(VALUE self)
|
163
|
+
{
|
164
|
+
krypt_asn1_template *template;
|
165
|
+
VALUE definition, klass;
|
166
|
+
|
167
|
+
if (DATA_PTR(self))
|
168
|
+
rb_raise(eKryptASN1Error, "Template already initialized");
|
169
|
+
klass = CLASS_OF(self);
|
170
|
+
if (NIL_P((definition = krypt_definition_get(klass)))) {
|
171
|
+
krypt_error_add("%s has no ASN.1 definition", rb_class2name(klass));
|
172
|
+
return Qnil;
|
173
|
+
}
|
174
|
+
template = krypt_asn1_template_new(NULL, definition, krypt_hash_get_options(definition));
|
175
|
+
krypt_asn1_template_set_parsed(template, 1);
|
176
|
+
krypt_asn1_template_set_decoded(template, 1);
|
177
|
+
DATA_PTR(self) = template;
|
178
|
+
|
179
|
+
if (rb_block_given_p()) {
|
180
|
+
VALUE blk = rb_block_proc();
|
181
|
+
rb_funcall(blk, rb_intern("call"), 1, self);
|
182
|
+
}
|
183
|
+
return self;
|
184
|
+
}
|
185
|
+
|
186
|
+
static VALUE
|
187
|
+
krypt_asn1_template_alloc(VALUE klass)
|
188
|
+
{
|
189
|
+
return Data_Wrap_Struct(klass, krypt_asn1_template_mark, krypt_asn1_template_free, 0);
|
190
|
+
}
|
191
|
+
|
192
|
+
static VALUE
|
193
|
+
int_traverse_template(VALUE vt,
|
194
|
+
VALUE name,
|
195
|
+
void (*traverse_cb) (VALUE, VALUE, void *),
|
196
|
+
void *args)
|
197
|
+
{
|
198
|
+
ID codec;
|
199
|
+
VALUE vcodec, definition;
|
200
|
+
krypt_asn1_template *t;
|
201
|
+
|
202
|
+
traverse_cb(vt, name, args);
|
203
|
+
|
204
|
+
if (NIL_P(vt)) {
|
205
|
+
/* base case 1 */
|
206
|
+
return Qnil;
|
207
|
+
}
|
208
|
+
|
209
|
+
krypt_asn1_template_get(vt, t);
|
210
|
+
|
211
|
+
definition = krypt_asn1_template_get_definition(t);
|
212
|
+
if (NIL_P(definition)) {
|
213
|
+
/* base case 2 */
|
214
|
+
return Qnil;
|
215
|
+
}
|
216
|
+
|
217
|
+
get_or_raise(vcodec, krypt_hash_get_codec(definition), "No codec found in definition");
|
218
|
+
codec = SYM2ID(vcodec);
|
219
|
+
if (codec == sKrypt_ID_PRIMITIVE) {
|
220
|
+
/* base case 3 */
|
221
|
+
return Qnil;
|
222
|
+
}
|
223
|
+
if (codec == sKrypt_ID_ANY ||
|
224
|
+
codec == sKrypt_ID_CHOICE ||
|
225
|
+
codec == sKrypt_ID_SET_OF ||
|
226
|
+
codec == sKrypt_ID_SEQUENCE_OF) {
|
227
|
+
VALUE name = krypt_hash_get_name(definition);
|
228
|
+
VALUE value = rb_ivar_get(vt, sKrypt_IV_VALUE);
|
229
|
+
return int_traverse_template(value, name, traverse_cb, args);
|
230
|
+
}
|
231
|
+
if (codec == sKrypt_ID_SET || codec == sKrypt_ID_SEQUENCE) {
|
232
|
+
long i;
|
233
|
+
VALUE dummy = Qnil;
|
234
|
+
VALUE layout = krypt_hash_get_layout(definition);
|
235
|
+
for (i=0; i < RARRAY_LEN(layout); ++i) {
|
236
|
+
VALUE name, value;
|
237
|
+
VALUE cur_def = rb_ary_entry(layout, i);
|
238
|
+
|
239
|
+
get_or_raise(name, krypt_hash_get_name(cur_def), "SEQ/SET value without name found");
|
240
|
+
value = rb_ivar_get(vt, SYM2ID(name));
|
241
|
+
dummy = int_traverse_template(value, name, traverse_cb, args);
|
242
|
+
}
|
243
|
+
return dummy;
|
244
|
+
}
|
245
|
+
if (codec == sKrypt_ID_TEMPLATE) {
|
246
|
+
return int_traverse_template(t->value, name, traverse_cb, args);
|
247
|
+
}
|
248
|
+
|
249
|
+
rb_raise(eKryptASN1Error, "Unknown codec encountered: %s", rb_id2name(codec));
|
250
|
+
return Qnil;
|
251
|
+
}
|
252
|
+
|
253
|
+
static VALUE
|
254
|
+
krypt_asn1_template_mod_included_callback(VALUE self, VALUE klass)
|
255
|
+
{
|
256
|
+
rb_define_alloc_func(klass, krypt_asn1_template_alloc);
|
257
|
+
return Qnil;
|
258
|
+
}
|
259
|
+
|
260
|
+
static VALUE
|
261
|
+
int_return_choice_attr(VALUE self, ID ivname)
|
262
|
+
{
|
263
|
+
VALUE dummy;
|
264
|
+
|
265
|
+
if (krypt_asn1_template_get_cb_value(self, sKrypt_IV_VALUE, &dummy) == KRYPT_ERR) {
|
266
|
+
krypt_error_raise(eKryptASN1Error, "Could not access %s", rb_id2name(ivname));
|
267
|
+
}
|
268
|
+
return rb_ivar_get(self, ivname);
|
269
|
+
}
|
270
|
+
|
271
|
+
VALUE
|
272
|
+
krypt_asn1_template_get_callback(VALUE self, VALUE name)
|
273
|
+
{
|
274
|
+
VALUE ret = Qnil;
|
275
|
+
ID ivname = SYM2ID(name);
|
276
|
+
|
277
|
+
if (krypt_asn1_template_get_cb_value(self, ivname, &ret) == KRYPT_ERR)
|
278
|
+
krypt_error_raise(eKryptASN1Error, "Could not access %s", rb_id2name(ivname));
|
279
|
+
return ret;
|
280
|
+
}
|
281
|
+
|
282
|
+
VALUE
|
283
|
+
krypt_asn1_template_get_callback_choice(VALUE self, VALUE name)
|
284
|
+
{
|
285
|
+
ID ivname = SYM2ID(name);
|
286
|
+
|
287
|
+
if (ivname == sKrypt_IV_TAG || ivname == sKrypt_IV_TYPE)
|
288
|
+
return int_return_choice_attr(self, ivname);
|
289
|
+
|
290
|
+
return krypt_asn1_template_get_callback(self, name);
|
291
|
+
}
|
292
|
+
|
293
|
+
VALUE
|
294
|
+
krypt_asn1_template_set_callback(VALUE self, VALUE name, VALUE value)
|
295
|
+
{
|
296
|
+
ID ivname = SYM2ID(name);
|
297
|
+
krypt_asn1_template_set_cb_value(self, ivname, value);
|
298
|
+
return value;
|
299
|
+
}
|
300
|
+
|
301
|
+
VALUE
|
302
|
+
krypt_asn1_template_set_callback_choice(VALUE self, VALUE name, VALUE value)
|
303
|
+
{
|
304
|
+
ID ivname = SYM2ID(name);
|
305
|
+
|
306
|
+
if (ivname == sKrypt_IV_TAG || ivname == sKrypt_IV_TYPE)
|
307
|
+
return rb_ivar_set(self, ivname, value);
|
308
|
+
|
309
|
+
return krypt_asn1_template_set_callback(self, name, value);
|
310
|
+
}
|
311
|
+
|
312
|
+
VALUE
|
313
|
+
krypt_asn1_template_cmp(VALUE self, VALUE other)
|
314
|
+
{
|
315
|
+
VALUE vs1, vs2;
|
316
|
+
int result;
|
317
|
+
|
318
|
+
vs1 = krypt_asn1_template_to_der(self);
|
319
|
+
if (!rb_respond_to(other, sKrypt_ID_TO_DER)) return Qnil;
|
320
|
+
vs2 = krypt_to_der(other);
|
321
|
+
|
322
|
+
if (krypt_asn1_cmp_set_of((uint8_t *) RSTRING_PTR(vs1), (size_t) RSTRING_LEN(vs1),
|
323
|
+
(uint8_t *) RSTRING_PTR(vs2), (size_t) RSTRING_LEN(vs2), &result) == KRYPT_ERR) {
|
324
|
+
krypt_error_raise(eKryptASN1Error, "Error while comparing values");
|
325
|
+
}
|
326
|
+
return INT2NUM(result);
|
327
|
+
}
|
328
|
+
|
329
|
+
static void
|
330
|
+
int_inspect_i(VALUE template_value, VALUE name, void *args)
|
331
|
+
{
|
332
|
+
krypt_asn1_template *t;
|
333
|
+
krypt_asn1_object *object;
|
334
|
+
VALUE definition, codec, str;
|
335
|
+
ID puts = rb_intern("puts");
|
336
|
+
ID to_s = rb_intern("to_s");
|
337
|
+
VALUE yes = rb_str_new2("y"), no = rb_str_new2("n");
|
338
|
+
|
339
|
+
str = rb_str_new2("Name: ");
|
340
|
+
rb_str_append(str, rb_funcall(name, to_s, 0));
|
341
|
+
if (NIL_P(template_value)) {
|
342
|
+
rb_str_append(str, rb_str_new2(" @value"));
|
343
|
+
rb_funcall(rb_mKernel, puts, 1, str);
|
344
|
+
return;
|
345
|
+
}
|
346
|
+
|
347
|
+
krypt_asn1_template_get(template_value, t);
|
348
|
+
|
349
|
+
definition = krypt_asn1_template_get_definition(t);
|
350
|
+
codec = NIL_P(definition) ? rb_str_new2("") : krypt_hash_get_codec(definition);
|
351
|
+
|
352
|
+
rb_str_append(str, rb_str_new2(" Codec: "));
|
353
|
+
rb_str_append(str, rb_funcall(codec, to_s, 0));
|
354
|
+
rb_str_append(str, rb_str_new2(" Parsed: "));
|
355
|
+
rb_str_append(str, krypt_asn1_template_is_parsed(t) ? yes : no);
|
356
|
+
rb_str_append(str, rb_str_new2(" Decoded: "));
|
357
|
+
rb_str_append(str, krypt_asn1_template_is_decoded(t) ? yes : no);
|
358
|
+
rb_str_append(str, rb_str_new2(" Modified: "));
|
359
|
+
rb_str_append(str, krypt_asn1_template_is_modified(t) ? yes : no);
|
360
|
+
rb_str_append(str, rb_str_new2(" Object: "));
|
361
|
+
object = krypt_asn1_template_get_object(t);
|
362
|
+
rb_str_append(str, object ? yes : no);
|
363
|
+
rb_str_append(str, rb_str_new2(" Bytes: "));
|
364
|
+
rb_str_append(str, (object && object->bytes) ? yes : no);
|
365
|
+
rb_funcall(rb_mKernel, puts, 1, str);
|
366
|
+
|
367
|
+
str = rb_str_new2("Value: ");
|
368
|
+
rb_str_append(str, rb_funcall(krypt_asn1_template_get_value(t), to_s, 0));
|
369
|
+
rb_funcall(rb_mKernel, puts, 1, str);
|
370
|
+
|
371
|
+
str = rb_str_new2("Definition: ");
|
372
|
+
rb_str_append(str, rb_funcall(krypt_asn1_template_get_definition(t), to_s, 0));
|
373
|
+
rb_funcall(rb_mKernel, puts, 1, str);
|
374
|
+
|
375
|
+
str = rb_str_new2("Options: ");
|
376
|
+
rb_str_append(str, rb_funcall(krypt_asn1_template_get_options(t), to_s, 0));
|
377
|
+
rb_funcall(rb_mKernel, puts, 1, str);
|
378
|
+
}
|
379
|
+
|
380
|
+
static VALUE
|
381
|
+
krypt_asn1_template_inspect(VALUE self)
|
382
|
+
{
|
383
|
+
VALUE name = rb_str_new2("ROOT");
|
384
|
+
return int_traverse_template(self, name, int_inspect_i, NULL);
|
385
|
+
}
|
386
|
+
|
387
|
+
/*
|
388
|
+
* call-seq:
|
389
|
+
* asn1.to_der -> DER-/BER-encoded String
|
390
|
+
*
|
391
|
+
* Behaves the same way that Krypt::ASN1#to_der does.
|
392
|
+
*/
|
393
|
+
VALUE
|
394
|
+
krypt_asn1_template_to_der(VALUE template)
|
395
|
+
{
|
396
|
+
VALUE ret;
|
397
|
+
|
398
|
+
if (krypt_asn1_template_encode(template, &ret) == KRYPT_ERR)
|
399
|
+
krypt_error_raise(eKryptASN1Error, "Error while encoding value");
|
400
|
+
return ret;
|
401
|
+
}
|
402
|
+
|
403
|
+
static VALUE
|
404
|
+
krypt_asn1_template_value_to_s(VALUE self)
|
405
|
+
{
|
406
|
+
krypt_asn1_template *template;
|
407
|
+
|
408
|
+
krypt_asn1_template_get(self, template);
|
409
|
+
if (NIL_P(template->value))
|
410
|
+
return rb_str_new2("");
|
411
|
+
return rb_funcall(template->value, rb_intern("to_s"), 0);
|
412
|
+
}
|
413
|
+
|
414
|
+
void
|
415
|
+
Init_krypt_asn1_template(void)
|
416
|
+
{
|
417
|
+
sKrypt_ID_CODEC = rb_intern("codec");
|
418
|
+
sKrypt_ID_OPTIONS = rb_intern("options");
|
419
|
+
sKrypt_ID_DEFAULT = rb_intern("default");
|
420
|
+
sKrypt_ID_NAME = rb_intern("name");
|
421
|
+
sKrypt_ID_TYPE = rb_intern("type");
|
422
|
+
sKrypt_ID_OPTIONAL = rb_intern("optional");
|
423
|
+
sKrypt_ID_TAG = rb_intern("tag");
|
424
|
+
sKrypt_ID_TAGGING = rb_intern("tagging");
|
425
|
+
sKrypt_ID_LAYOUT = rb_intern("layout");
|
426
|
+
sKrypt_ID_MIN_SIZE = rb_intern("min_size");
|
427
|
+
|
428
|
+
sKrypt_ID_PRIMITIVE = rb_intern("PRIMITIVE");
|
429
|
+
sKrypt_ID_SEQUENCE = rb_intern("SEQUENCE");
|
430
|
+
sKrypt_ID_SET = rb_intern("SET");
|
431
|
+
sKrypt_ID_TEMPLATE = rb_intern("TEMPLATE");
|
432
|
+
sKrypt_ID_SEQUENCE_OF = rb_intern("SEQUENCE_OF");
|
433
|
+
sKrypt_ID_SET_OF = rb_intern("SET_OF");
|
434
|
+
sKrypt_ID_CHOICE = rb_intern("CHOICE");
|
435
|
+
sKrypt_ID_ANY = rb_intern("ANY");
|
436
|
+
|
437
|
+
sKrypt_IV_TYPE = rb_intern("@type");
|
438
|
+
sKrypt_IV_DEFINITION = rb_intern("@definition");
|
439
|
+
sKrypt_IV_OPTIONS = rb_intern("@options");
|
440
|
+
|
441
|
+
sKrypt_ID_MERGE = rb_intern("merge");
|
442
|
+
|
443
|
+
mKryptASN1Template = rb_define_module_under(mKryptASN1, "Template");
|
444
|
+
rb_define_module_function(mKryptASN1Template, "_mod_included_callback", krypt_asn1_template_mod_included_callback, 1);
|
445
|
+
rb_define_method(mKryptASN1Template, "initialize", krypt_asn1_template_initialize, 0);
|
446
|
+
rb_define_method(mKryptASN1Template, "_get_callback", krypt_asn1_template_get_callback, 1);
|
447
|
+
rb_define_method(mKryptASN1Template, "_set_callback", krypt_asn1_template_set_callback, 2);
|
448
|
+
rb_define_method(mKryptASN1Template, "_get_callback_choice", krypt_asn1_template_get_callback_choice, 1);
|
449
|
+
rb_define_method(mKryptASN1Template, "_set_callback_choice", krypt_asn1_template_set_callback_choice, 2);
|
450
|
+
rb_define_method(mKryptASN1Template, "to_der", krypt_asn1_template_to_der, 0);
|
451
|
+
rb_define_method(mKryptASN1Template, "<=>", krypt_asn1_template_cmp, 1);
|
452
|
+
rb_define_method(mKryptASN1Template, "__inspect__", krypt_asn1_template_inspect, 0);
|
453
|
+
|
454
|
+
cKryptASN1TemplateValue = rb_define_class_under(mKryptASN1Template, "Value", rb_cObject);
|
455
|
+
rb_define_method(cKryptASN1TemplateValue, "to_s", krypt_asn1_template_value_to_s, 0);
|
456
|
+
|
457
|
+
Init_krypt_asn1_template_parser();
|
458
|
+
}
|
459
|
+
|
@@ -0,0 +1,56 @@
|
|
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
|
+
#if !defined(_KRYPT_ASN1_TEMPLATE_H_)
|
30
|
+
#define _KRYPT_ASN1_TEMPLATE_H_
|
31
|
+
|
32
|
+
extern ID sKrypt_ID_OPTIONS, sKrypt_ID_NAME, sKrypt_ID_TYPE,
|
33
|
+
sKrypt_ID_CODEC, sKrypt_ID_LAYOUT, sKrypt_ID_MIN_SIZE;
|
34
|
+
|
35
|
+
extern ID sKrypt_ID_DEFAULT, sKrypt_ID_OPTIONAL, sKrypt_ID_TAG, sKrypt_ID_TAGGING;
|
36
|
+
|
37
|
+
extern ID sKrypt_ID_DEFAULT, sKrypt_ID_NAME, sKrypt_ID_TYPE,
|
38
|
+
sKrypt_ID_OPTIONAL, sKrypt_ID_TAG, sKrypt_ID_TAGGING,
|
39
|
+
sKrypt_ID_LAYOUT, sKrypt_ID_MIN_SIZE, sKrypt_ID_CODEC;
|
40
|
+
|
41
|
+
extern ID sKrypt_ID_PRIMITIVE, sKrypt_ID_SEQUENCE, sKrypt_ID_SET, sKrypt_ID_TEMPLATE,
|
42
|
+
sKrypt_ID_SEQUENCE_OF, sKrypt_ID_SET_OF, sKrypt_ID_CHOICE, sKrypt_ID_ANY;
|
43
|
+
|
44
|
+
extern ID sKrypt_IV_VALUE, sKrypt_IV_DEFINITION, sKrypt_IV_OPTIONS;
|
45
|
+
|
46
|
+
extern ID sKrypt_ID_MERGE;
|
47
|
+
|
48
|
+
extern VALUE mKryptASN1Template;
|
49
|
+
|
50
|
+
VALUE krypt_asn1_template_parse_der(VALUE klass, VALUE der);
|
51
|
+
VALUE krypt_asn1_template_to_der(VALUE templ);
|
52
|
+
|
53
|
+
void Init_krypt_asn1_template(void);
|
54
|
+
|
55
|
+
#endif /*_KRYPT_ASN1_TEMPLATE_H_ */
|
56
|
+
|
Binary file
|