12 static VALUE ossl_asn1_decode0(
unsigned char **pp,
long length,
long *offset,
13 int depth,
int yield,
long *num_read);
26 memset(&tm, 0,
sizeof(
struct tm));
30 count = sscanf((
const char *)time->data,
"%2d%2d%2d%2d%2d%2dZ",
31 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
36 }
else if (count != 6) {
40 if (tm.tm_year < 69) {
46 case V_ASN1_GENERALIZEDTIME:
47 count = sscanf((
const char *)time->data,
"%4d%2d%2d%2d%2d%2dZ",
48 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
53 else if (count != 6) {
94 return rb_str_new((
const char *)str->data, str->length);
109 if (ai->type == V_ASN1_ENUMERATED)
111 bn = ASN1_ENUMERATED_to_BN((ASN1_ENUMERATED *)ai,
NULL);
113 bn = ASN1_INTEGER_to_BN(ai,
NULL);
133 if (!(ai = BN_to_ASN1_INTEGER(bn, ai)))
143 #define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE) 144 #define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG) 145 #define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING) 146 #define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS) 147 #define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH) 149 #define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v)) 150 #define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v)) 151 #define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v)) 152 #define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v)) 153 #define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v)) 177 static VALUE sym_IMPLICIT, sym_EXPLICIT;
178 static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
179 static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS;
186 obj_to_asn1bool(
VALUE obj)
191 return RTEST(obj) ? 0xff : 0x0;
195 obj_to_asn1int(
VALUE obj)
200 static ASN1_BIT_STRING*
201 obj_to_asn1bstr(
VALUE obj,
long unused_bits)
203 ASN1_BIT_STRING *bstr;
205 if (unused_bits < 0 || unused_bits > 7)
209 if(!(bstr = ASN1_BIT_STRING_new()))
212 bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
213 bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
219 obj_to_asn1str(
VALUE obj)
224 if(!(str = ASN1_STRING_new()))
232 obj_to_asn1null(
VALUE obj)
238 if(!(null = ASN1_NULL_new()))
245 obj_to_asn1obj(
VALUE obj)
251 if(!a1obj) a1obj = OBJ_txt2obj(
RSTRING_PTR(obj), 1);
257 static ASN1_UTCTIME *
258 obj_to_asn1utime(
VALUE time)
266 if (!(t = ASN1_UTCTIME_adj(
NULL, sec, off_days, 0)))
272 static ASN1_GENERALIZEDTIME *
273 obj_to_asn1gtime(
VALUE time)
276 ASN1_GENERALIZEDTIME *t;
281 if (!(t = ASN1_GENERALIZEDTIME_adj(
NULL, sec, off_days, 0)))
288 obj_to_asn1derstr(
VALUE obj)
294 if(!(a1str = ASN1_STRING_new()))
305 decode_bool(
unsigned char* der,
long length)
307 const unsigned char *p = der;
311 if (p[0] != 1 || p[1] != 1)
318 decode_int(
unsigned char* der,
long length)
321 const unsigned char *p;
326 if(!(ai = d2i_ASN1_INTEGER(
NULL, &p, length)))
330 ASN1_INTEGER_free(ai);
337 decode_bstr(
unsigned char* der,
long length,
long *unused_bits)
339 ASN1_BIT_STRING *bstr;
340 const unsigned char *p;
345 if(!(bstr = d2i_ASN1_BIT_STRING(
NULL, &p, length)))
349 if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
350 *unused_bits = bstr->flags & 0x07;
351 ret =
rb_str_new((
const char *)bstr->data, len);
352 ASN1_BIT_STRING_free(bstr);
358 decode_enum(
unsigned char* der,
long length)
361 const unsigned char *p;
366 if(!(ai = d2i_ASN1_ENUMERATED(
NULL, &p, length)))
370 ASN1_ENUMERATED_free(ai);
377 decode_null(
unsigned char* der,
long length)
380 const unsigned char *p;
383 if(!(null = d2i_ASN1_NULL(
NULL, &p, length)))
385 ASN1_NULL_free(null);
391 decode_obj(
unsigned char* der,
long length)
394 const unsigned char *p;
400 if(!(obj = d2i_ASN1_OBJECT(
NULL, &p, length)))
402 if((nid = OBJ_obj2nid(obj)) != NID_undef){
403 ASN1_OBJECT_free(obj);
407 if(!(bio = BIO_new(BIO_s_mem()))){
408 ASN1_OBJECT_free(obj);
411 i2a_ASN1_OBJECT(bio, obj);
412 ASN1_OBJECT_free(obj);
420 decode_time(
unsigned char* der,
long length)
423 const unsigned char *p;
428 if(!(time = d2i_ASN1_TIME(
NULL, &p, length)))
431 (
VALUE)time, &status);
432 ASN1_TIME_free(time);
439 decode_eoc(
unsigned char *der,
long length)
441 if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00))
462 {
"OBJECT_DESCRIPTOR",
NULL, },
463 {
"EXTERNAL",
NULL, },
466 {
"EMBEDDED_PDV",
NULL, },
468 {
"RELATIVE_OID",
NULL, },
469 {
"[UNIVERSAL 14]",
NULL, },
470 {
"[UNIVERSAL 15]",
NULL, },
484 {
"CHARACTER_STRING",
NULL, },
490 static VALUE class_tag_map;
492 static int ossl_asn1_default_tag(
VALUE obj);
503 tag = ossl_asn1_default_tag(obj);
507 ptr = (
void*)(
VALUE)obj_to_asn1bool(value);
511 case V_ASN1_ENUMERATED:
512 ptr = obj_to_asn1int(value);
513 free_func = ASN1_INTEGER_free;
515 case V_ASN1_BIT_STRING:
517 ptr = obj_to_asn1bstr(value,
NUM2INT(rflag));
518 free_func = ASN1_BIT_STRING_free;
521 ptr = obj_to_asn1null(value);
522 free_func = ASN1_NULL_free;
524 case V_ASN1_OCTET_STRING:
525 case V_ASN1_UTF8STRING:
526 case V_ASN1_NUMERICSTRING:
527 case V_ASN1_PRINTABLESTRING:
528 case V_ASN1_T61STRING:
529 case V_ASN1_VIDEOTEXSTRING:
530 case V_ASN1_IA5STRING:
531 case V_ASN1_GRAPHICSTRING:
532 case V_ASN1_ISO64STRING:
533 case V_ASN1_GENERALSTRING:
534 case V_ASN1_UNIVERSALSTRING:
535 case V_ASN1_BMPSTRING:
536 ptr = obj_to_asn1str(value);
537 free_func = ASN1_STRING_free;
540 ptr = obj_to_asn1obj(value);
541 free_func = ASN1_OBJECT_free;
544 ptr = obj_to_asn1utime(value);
545 free_func = ASN1_TIME_free;
547 case V_ASN1_GENERALIZEDTIME:
548 ptr = obj_to_asn1gtime(value);
549 free_func = ASN1_TIME_free;
552 case V_ASN1_SEQUENCE:
553 ptr = obj_to_asn1derstr(obj);
554 free_func = ASN1_STRING_free;
559 if(!(ret = OPENSSL_malloc(
sizeof(ASN1_TYPE)))){
560 if(free_func) free_func(ptr);
563 memset(ret, 0,
sizeof(ASN1_TYPE));
564 ASN1_TYPE_set(ret, tag, ptr);
570 ossl_asn1_default_tag(
VALUE obj)
572 VALUE tmp_class, tag;
575 while (!
NIL_P(tmp_class)) {
586 ossl_asn1_tag(
VALUE obj)
598 ossl_asn1_tag_class(
VALUE obj)
603 if (
NIL_P(s) || s == sym_UNIVERSAL)
604 return V_ASN1_UNIVERSAL;
605 else if (s == sym_APPLICATION)
606 return V_ASN1_APPLICATION;
607 else if (s == sym_CONTEXT_SPECIFIC)
608 return V_ASN1_CONTEXT_SPECIFIC;
609 else if (s == sym_PRIVATE)
610 return V_ASN1_PRIVATE;
616 ossl_asn1_class2sym(
int tc)
618 if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
620 else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
621 return sym_CONTEXT_SPECIFIC;
622 else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
623 return sym_APPLICATION;
625 return sym_UNIVERSAL;
658 to_der_internal(
VALUE self,
int constructed,
int indef_len,
VALUE body)
660 int encoding = constructed ? indef_len ? 2 : 1 : 0;
661 int tag_class = ossl_asn1_tag_class(
self);
662 int tag_number = ossl_asn1_tag(
self);
663 int default_tag_number = ossl_asn1_default_tag(
self);
664 int body_length, total_length;
670 int inner_length, e_encoding = indef_len ? 2 : 1;
672 if (default_tag_number == -1)
675 inner_length = ASN1_object_size(encoding, body_length, default_tag_number);
676 total_length = ASN1_object_size(e_encoding, inner_length, tag_number);
680 ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class);
682 ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL);
691 total_length = ASN1_object_size(encoding, body_length, tag_number);
694 ASN1_put_object(&p, encoding, body_length, tag_number, tag_class);
716 ossl_asn1data_to_der(
VALUE self)
721 return ossl_asn1cons_to_der(
self);
725 "with primitive encoding");
726 return ossl_asn1prim_to_der(
self);
731 int_ossl_asn1_decode0_prim(
unsigned char **pp,
long length,
long hlen,
int tag,
732 VALUE tc,
long *num_read)
734 VALUE value, asn1data;
743 value = decode_eoc(p, hlen+length);
746 value = decode_bool(p, hlen+length);
749 value = decode_int(p, hlen+length);
751 case V_ASN1_BIT_STRING:
752 value = decode_bstr(p, hlen+length, &flag);
755 value = decode_null(p, hlen+length);
757 case V_ASN1_ENUMERATED:
758 value = decode_enum(p, hlen+length);
761 value = decode_obj(p, hlen+length);
764 case V_ASN1_GENERALIZEDTIME:
765 value = decode_time(p, hlen+length);
779 *pp += hlen + length;
780 *num_read = hlen + length;
782 if (tc == sym_UNIVERSAL &&
791 ossl_asn1_initialize(4, args, asn1data);
792 if(tag == V_ASN1_BIT_STRING){
798 ossl_asn1data_initialize(asn1data, value,
INT2NUM(tag), tc);
805 int_ossl_asn1_decode0_cons(
unsigned char **pp,
long max_len,
long length,
806 long *offset,
int depth,
int yield,
int j,
807 int tag,
VALUE tc,
long *num_read)
809 VALUE value, asn1data, ary;
811 long available_len, off = *offset;
813 indefinite = (j == 0x21);
816 available_len = indefinite ? max_len : length;
817 while (available_len > 0) {
819 value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read);
820 *num_read += inner_read;
821 available_len -= inner_read;
824 ossl_asn1_tag(value) == V_ASN1_EOC &&
831 if (tc == sym_UNIVERSAL) {
833 if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET)
841 ossl_asn1_initialize(4, args, asn1data);
845 ossl_asn1data_initialize(asn1data, ary,
INT2NUM(tag), tc);
858 ossl_asn1_decode0(
unsigned char **pp,
long length,
long *offset,
int depth,
859 int yield,
long *num_read)
861 unsigned char *start, *p;
862 const unsigned char *p0;
863 long len = 0, inner_read = 0, off = *offset, hlen;
865 VALUE asn1data, tag_class;
870 j = ASN1_get_object(&p0, &len, &tag, &tc, length);
871 p = (
unsigned char *)p0;
874 if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
875 tag_class = sym_PRIVATE;
876 else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
877 tag_class = sym_CONTEXT_SPECIFIC;
878 else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
879 tag_class = sym_APPLICATION;
881 tag_class = sym_UNIVERSAL;
897 if(j & V_ASN1_CONSTRUCTED) {
900 asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read);
904 if ((j & 0x01) && (len == 0))
906 asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read);
910 *num_read = inner_read;
911 if (len != 0 && inner_read != hlen + len) {
913 "Type mismatch. Bytes read: %ld Bytes available: %ld",
914 inner_read, hlen + len);
922 int_ossl_decode_sanity_check(
long len,
long read,
long offset)
924 if (
len != 0 && (read !=
len || offset !=
len)) {
926 "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
957 long len, read = 0, offset = 0;
963 ossl_asn1_decode0(&p, len, &offset, 0, 1, &read);
965 int_ossl_decode_sanity_check(len, read, offset);
987 long len, read = 0, offset = 0;
993 ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read);
995 int_ossl_decode_sanity_check(len, read, offset);
1017 long len, tmp_len = 0, read = 0, offset = 0;
1026 while (tmp_len > 0) {
1028 val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read);
1031 tmp_len -= tmp_read;
1034 int_ossl_decode_sanity_check(len, read, offset);
1064 VALUE value, tag, tagging, tag_class;
1068 default_tag = ossl_asn1_default_tag(
self);
1070 if (default_tag == -1 ||
argc > 1) {
1075 if(
NIL_P(tag_class)) {
1077 tag_class = sym_UNIVERSAL;
1079 tag_class = sym_CONTEXT_SPECIFIC;
1087 tag_class = sym_UNIVERSAL;
1094 if (default_tag == V_ASN1_BIT_STRING)
1101 ossl_asn1eoc_initialize(
VALUE self) {
1102 VALUE tag, tagging, tag_class, value;
1105 tag_class = sym_UNIVERSAL;
1116 ossl_asn1eoc_to_der(
VALUE self)
1128 ossl_asn1prim_to_der(
VALUE self)
1131 long alllen, bodylen;
1132 unsigned char *p0, *p1;
1133 int j, tag, tc, state;
1136 if (ossl_asn1_default_tag(
self) == -1) {
1138 return to_der_internal(
self, 0, 0,
StringValue(str));
1142 alllen = i2d_ASN1_TYPE(asn1,
NULL);
1144 ASN1_TYPE_free(asn1);
1149 ASN1_TYPE_free(asn1);
1153 i2d_ASN1_TYPE(asn1, &p0);
1154 ASN1_TYPE_free(asn1);
1155 assert(p0 - p1 == alllen);
1158 j = ASN1_get_object((
const unsigned char **)&p1, &bodylen, &tag, &tc, alllen);
1172 ossl_asn1cons_to_der(
VALUE self)
1200 return to_der_internal(
self, 1, indef_len, str);
1217 ossl_asn1cons_each(
VALUE self)
1256 ossl_asn1obj_get_sn(
VALUE self)
1276 ossl_asn1obj_get_ln(
VALUE self)
1289 asn1obj_get_oid_i(
VALUE vobj)
1291 ASN1_OBJECT *a1obj = (
void *)vobj;
1297 if (len <= 0 || len == INT_MAX)
1302 len = OBJ_obj2txt(
RSTRING_PTR(str), len + 1, a1obj, 1);
1318 ossl_asn1obj_get_oid(
VALUE self)
1326 ASN1_OBJECT_free(a1obj);
1332 #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \ 1333 static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\ 1334 { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); } 1382 sivINDEFINITE_LENGTH =
rb_intern(
"@indefinite_length");
1383 sivUNUSED_BITS =
rb_intern(
"@unused_bits");
1526 if(ossl_asn1_info[i].
name[0] ==
'[')
continue;
1774 #define OSSL_ASN1_DEFINE_CLASS(name, super) \ 1776 cASN1##name = rb_define_class_under(mASN1, #name, cASN1##super);\ 1777 rb_define_module_function(mASN1, #name, ossl_asn1_##name, -1);\
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
#define ossl_asn1_get_tagging(o)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
VALUE cASN1PrintableString
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
void rb_str_set_len(VALUE, long)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
#define ossl_asn1_set_value(o, v)
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
void Init_ossl_asn1(void)
void rb_include_module(VALUE klass, VALUE module)
VALUE rb_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
VALUE rb_hash_lookup(VALUE hash, VALUE key)
VALUE asn1integer_to_num(const ASN1_INTEGER *ai)
#define ossl_asn1_get_tag_class(o)
VALUE ossl_membio2str(BIO *bio)
void rb_undef_method(VALUE klass, const char *name)
#define ossl_asn1_set_tagging(o, v)
void rb_global_variable(VALUE *var)
#define ossl_asn1_set_indefinite_length(o, v)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
VALUE ossl_to_der_if_possible(VALUE obj)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE cASN1UniversalString
RUBY_EXTERN VALUE rb_cObject
void rb_attr(VALUE, ID, int, int, int)
#define OSSL_ASN1_DEFINE_CLASS(name, super)
#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass)
void rb_define_const(VALUE, const char *, VALUE)
void rb_ary_store(VALUE ary, long idx, VALUE val)
ASN1_TYPE * ossl_asn1_get_asn1type(VALUE obj)
VALUE rb_str_resize(VALUE, long)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
#define ossl_asn1_set_tag(o, v)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_ivar_set(VALUE, ID, VALUE)
#define ossl_asn1_get_indefinite_length(o)
#define ossl_asn1_set_tag_class(o, v)
void ossl_time_split(VALUE time, time_t *sec, int *days)
register unsigned int len
VALUE rb_define_module_under(VALUE outer, const char *name)
#define StringValueCStr(v)
VALUE asn1str_to_str(const ASN1_STRING *str)
#define RARRAY_AREF(a, i)
VALUE rb_class_superclass(VALUE)
call-seq: class.superclass -> a_super_class or nil
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Converts an object into another type.
VALUE asn1time_to_time(const ASN1_TIME *time)
void rb_warning(const char *fmt,...)
#define ossl_asn1_get_value(o)
void ossl_raise(VALUE exc, const char *fmt,...)
#define ossl_asn1_get_tag(o)
VALUE ossl_bn_new(const BIGNUM *bn)
VALUE rb_str_drop_bytes(VALUE, long)
VALUE cASN1VideotexString
#define RSTRING_LENINT(str)
VALUE ossl_str_new(const char *ptr, long len, int *pstate)
#define rb_intern_const(str)
VALUE rb_define_module(const char *name)
VALUE rb_usascii_str_new(const char *, long)
RUBY_EXTERN VALUE rb_cTime
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE cASN1GeneralizedTime
VALUE rb_str_append(VALUE, VALUE)
VALUE ossl_to_der(VALUE obj)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_str_new(const char *, long)
ASN1_INTEGER * num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)