13 #if defined(HAVE_SYS_TIME_H)
14 # include <sys/time.h>
15 #elif !defined(NT) && !defined(_WIN32)
24 int depth,
int yield,
long *num_read);
38 if (!time || !time->data)
return Qnil;
39 memset(&tm, 0,
sizeof(
struct tm));
43 count = sscanf((
const char *)time->data,
"%2d%2d%2d%2d%2d%2dZ",
44 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
49 }
else if (count != 6) {
53 if (tm.tm_year < 69) {
59 case V_ASN1_GENERALIZEDTIME:
60 if (sscanf((
const char *)time->data,
"%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
61 &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
96 return rb_str_new((
const char *)str->data, str->length);
103 #define DO_IT_VIA_RUBY 0
116 if (!(bn = ASN1_INTEGER_to_BN(ai,
NULL))) {
120 if (!(txt = BN_bn2dec(bn))) {
148 if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) {
166 if (!(ai = BN_to_ASN1_INTEGER(bn, ai)))
177 #define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE)
178 #define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
179 #define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
180 #define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
181 #define ossl_asn1_get_infinite_length(o) rb_attr_get((o),sivINFINITE_LENGTH)
183 #define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
184 #define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
185 #define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
186 #define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
187 #define ossl_asn1_set_infinite_length(o,v) rb_ivar_set((o),sivINFINITE_LENGTH,(v))
220 #if OPENSSL_VERSION_NUMBER < 0x00908000L
221 #define ossl_asn1_object_size(cons, len, tag) (cons) == 2 ? (len) + ASN1_object_size((cons), 0, (tag)) : ASN1_object_size((cons), (len), (tag))
222 #define ossl_asn1_put_object(pp, cons, len, tag, xc) (cons) == 2 ? ASN1_put_object((pp), (cons), 0, (tag), (xc)) : ASN1_put_object((pp), (cons), (len), (tag), (xc))
224 #define ossl_asn1_object_size(cons, len, tag) ASN1_object_size((cons), (len), (tag))
225 #define ossl_asn1_put_object(pp, cons, len, tag, xc) ASN1_put_object((pp), (cons), (len), (tag), (xc))
237 #if OPENSSL_VERSION_NUMBER < 0x00907000L
238 return RTEST(obj) ? 0xff : 0x100;
240 return RTEST(obj) ? 0xff : 0x0;
250 static ASN1_BIT_STRING*
253 ASN1_BIT_STRING *bstr;
255 if(unused_bits < 0) unused_bits = 0;
257 if(!(bstr = ASN1_BIT_STRING_new()))
260 bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
261 bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07);
272 if(!(str = ASN1_STRING_new()))
286 if(!(null = ASN1_NULL_new()))
299 if(!a1obj) a1obj = OBJ_txt2obj(
RSTRING_PTR(obj), 1);
300 if(!a1obj)
ossl_raise(eASN1Error,
"invalid OBJECT ID");
312 if(!(t = ASN1_UTCTIME_set(
NULL, sec)))
318 static ASN1_GENERALIZEDTIME*
322 ASN1_GENERALIZEDTIME *
t;
325 if(!(t =ASN1_GENERALIZEDTIME_set(
NULL, sec)))
338 if(!(a1str = ASN1_STRING_new()))
352 const unsigned char *
p;
355 if((val = d2i_ASN1_BOOLEAN(
NULL, &p, length)) < 0)
365 const unsigned char *
p;
370 if(!(ai = d2i_ASN1_INTEGER(
NULL, &p, length)))
374 ASN1_INTEGER_free(ai);
383 ASN1_BIT_STRING *bstr;
384 const unsigned char *
p;
389 if(!(bstr = d2i_ASN1_BIT_STRING(
NULL, &p, length)))
393 if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
394 *unused_bits = bstr->flags & 0x07;
395 ret =
rb_str_new((
const char *)bstr->data, len);
396 ASN1_BIT_STRING_free(bstr);
405 const unsigned char *
p;
410 if(!(ai = d2i_ASN1_ENUMERATED(
NULL, &p, length)))
414 ASN1_ENUMERATED_free(ai);
424 const unsigned char *
p;
427 if(!(null = d2i_ASN1_NULL(
NULL, &p, length)))
429 ASN1_NULL_free(null);
438 const unsigned char *
p;
444 if(!(obj = d2i_ASN1_OBJECT(
NULL, &p, length)))
446 if((nid = OBJ_obj2nid(obj)) != NID_undef){
447 ASN1_OBJECT_free(obj);
451 if(!(bio = BIO_new(BIO_s_mem()))){
452 ASN1_OBJECT_free(obj);
455 i2a_ASN1_OBJECT(bio, obj);
456 ASN1_OBJECT_free(obj);
467 const unsigned char *
p;
472 if(!(time = d2i_ASN1_TIME(
NULL, &p, length)))
475 (
VALUE)time, &status);
476 ASN1_TIME_free(time);
485 if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00))
506 {
"OBJECT_DESCRIPTOR",
NULL, },
507 {
"EXTERNAL",
NULL, },
510 {
"EMBEDDED_PDV",
NULL, },
512 {
"RELATIVE_OID",
NULL, },
513 {
"[UNIVERSAL 14]",
NULL, },
514 {
"[UNIVERSAL 15]",
NULL, },
528 {
"CHARACTER_STRING",
NULL, },
555 case V_ASN1_ENUMERATED:
557 free_func = ASN1_INTEGER_free;
559 case V_ASN1_BIT_STRING:
563 free_func = ASN1_BIT_STRING_free;
567 free_func = ASN1_NULL_free;
569 case V_ASN1_OCTET_STRING:
570 case V_ASN1_UTF8STRING:
571 case V_ASN1_NUMERICSTRING:
572 case V_ASN1_PRINTABLESTRING:
573 case V_ASN1_T61STRING:
574 case V_ASN1_VIDEOTEXSTRING:
575 case V_ASN1_IA5STRING:
576 case V_ASN1_GRAPHICSTRING:
577 case V_ASN1_ISO64STRING:
578 case V_ASN1_GENERALSTRING:
579 case V_ASN1_UNIVERSALSTRING:
580 case V_ASN1_BMPSTRING:
582 free_func = ASN1_STRING_free;
586 free_func = ASN1_OBJECT_free;
590 free_func = ASN1_TIME_free;
592 case V_ASN1_GENERALIZEDTIME:
594 free_func = ASN1_TIME_free;
597 case V_ASN1_SEQUENCE:
599 free_func = ASN1_STRING_free;
602 ossl_raise(eASN1Error,
"unsupported ASN.1 type");
604 if(!(ret = OPENSSL_malloc(
sizeof(ASN1_TYPE)))){
605 if(free_func) free_func(ptr);
606 ossl_raise(eASN1Error,
"ASN1_TYPE alloc failure");
608 memset(ret, 0,
sizeof(ASN1_TYPE));
609 ASN1_TYPE_set(ret, tag, ptr);
617 VALUE tmp_class, tag;
640 ossl_raise(eASN1Error,
"tag number not specified");
652 if(
NIL_P(s))
return 0;
654 if (
SYM2ID(s) == sIMPLICIT)
656 else if (
SYM2ID(s) == sEXPLICIT)
660 ossl_raise(eASN1Error,
"invalid tag default");
673 if(
NIL_P(s)) ret = V_ASN1_UNIVERSAL;
675 if (
SYM2ID(s) == sUNIVERSAL)
676 ret = V_ASN1_UNIVERSAL;
677 else if (
SYM2ID(s) == sAPPLICATION)
678 ret = V_ASN1_APPLICATION;
679 else if (
SYM2ID(s) == sCONTEXT_SPECIFIC)
680 ret = V_ASN1_CONTEXT_SPECIFIC;
681 else if (
SYM2ID(s) == sPRIVATE)
682 ret = V_ASN1_PRIVATE;
694 if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
696 else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
697 return ID2SYM(sCONTEXT_SPECIFIC);
698 else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
699 return ID2SYM(sAPPLICATION);
701 return ID2SYM(sUNIVERSAL);
726 ossl_raise(eASN1Error,
"tag number for Universal too large");
765 int tag, tag_class, is_cons = 0;
779 if (inf_length ==
Qtrue) {
796 VALUE tc,
long *num_read)
804 if(tc == sUNIVERSAL && tag < ossl_asn1_info_size) {
815 case V_ASN1_BIT_STRING:
821 case V_ASN1_ENUMERATED:
828 case V_ASN1_GENERALIZEDTIME:
844 *num_read = hlen +
length;
846 if (tc == sUNIVERSAL && tag < ossl_asn1_info_size && ossl_asn1_info[tag].
klass) {
855 if(tag == V_ASN1_BIT_STRING){
869 long *offset,
int depth,
int yield,
int j,
870 int tag,
VALUE tc,
long *num_read)
876 infinite = (j == 0x21);
879 while (length > 0 || infinite) {
882 *num_read += inner_read;
883 max_len -= inner_read;
886 length -= inner_read;
895 if (tc == sUNIVERSAL) {
897 int not_sequence_or_set;
899 not_sequence_or_set = tag != V_ASN1_SEQUENCE && tag != V_ASN1_SET;
901 if (not_sequence_or_set) {
906 ossl_raise(eASN1Error,
"invalid non-infinite tag");
936 int yield,
long *num_read)
938 unsigned char *start, *
p;
939 const unsigned char *p0;
940 long len = 0, inner_read = 0, off = *offset, hlen;
942 VALUE asn1data, tag_class;
947 j = ASN1_get_object(&p0, &len, &tag, &tc, length);
948 p = (
unsigned char *)p0;
950 if(len > length)
ossl_raise(eASN1Error,
"value is too short");
951 if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
953 else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
955 else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
974 if(j & V_ASN1_CONSTRUCTED) {
981 if ((j & 0x01) && (len == 0))
ossl_raise(eASN1Error,
"Infinite length for primitive value");
986 *num_read = inner_read;
987 if (len != 0 && inner_read != hlen + len) {
989 "Type mismatch. Bytes read: %ld Bytes available: %ld",
990 inner_read, hlen + len);
1000 if (len != 0 && (read != len || offset != len)) {
1002 "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
1033 long len, read = 0, offset = 0;
1062 long len, read = 0, offset = 0;
1091 long len, tmp_len = 0, read = 0, offset = 0;
1100 while (tmp_len > 0) {
1105 tmp_len -= tmp_read;
1139 rb_scan_args(argc, argv,
"13", &value, &tag, &tagging, &tag_class);
1142 ossl_raise(eASN1Error,
"must specify tag number");
1144 ossl_raise(eASN1Error,
"invalid tagging method");
1145 if(
NIL_P(tag_class)) {
1147 tag_class =
ID2SYM(sUNIVERSAL);
1149 tag_class =
ID2SYM(sCONTEXT_SPECIFIC);
1154 ossl_raise(eASN1Error,
"tag number for Universal too large");
1159 tag_class =
ID2SYM(sUNIVERSAL);
1175 tag_class =
ID2SYM(sUNIVERSAL);
1188 #if OPENSSL_VERSION_NUMBER < 0x00907000L
1190 if(a->type == V_ASN1_BOOLEAN)
1191 return i2d_ASN1_BOOLEAN(a->value.boolean, pp);
1193 return i2d_ASN1_TYPE(a, pp);
1199 #if OPENSSL_VERSION_NUMBER < 0x00907000L
1201 if(a->type == V_ASN1_BOOLEAN){
1219 int tn, tc,
explicit;
1221 unsigned char *
buf, *
p;
1230 if(!(buf = OPENSSL_malloc(len))){
1232 ossl_raise(eASN1Error,
"cannot alloc buffer");
1235 if (tc == V_ASN1_UNIVERSAL) {
1237 }
else if (
explicit) {
1242 *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
1261 int tag, tn, tc,
explicit, constructed = 1;
1262 int found_prim = 0, seq_len;
1270 if (inf_length ==
Qtrue) {
1273 if (
CLASS_OF(
self) == cASN1Sequence ||
1280 ossl_raise(eASN1Error,
"Constructive value must be an Array");
1285 while (!found_prim){
1293 ossl_raise(eASN1Error,
"invalid constructed encoding");
1303 if (
CLASS_OF(
self) == cASN1Constructive)
1304 ossl_raise(eASN1Error,
"Constructive shall only be used with infinite length");
1314 if(tc == V_ASN1_UNIVERSAL)
1333 if (
explicit && inf_length ==
Qtrue) {
1409 OBJ_obj2txt(buf,
sizeof(buf), a1obj, 1);
1410 ASN1_OBJECT_free(a1obj);
1415 #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
1416 static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
1417 { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); }
1454 sCONTEXT_SPECIFIC =
rb_intern(
"CONTEXT_SPECIFIC");
1455 sAPPLICATION =
rb_intern(
"APPLICATION");
1464 sivINFINITE_LENGTH =
rb_intern(
"@infinite_length");
1465 sivUNUSED_BITS =
rb_intern(
"@unused_bits");
1611 if(ossl_asn1_info[i].
name[0] ==
'[')
continue;
1887 #define OSSL_ASN1_DEFINE_CLASS(name, super) \
1889 cASN1##name = rb_define_class_under(mASN1, #name, cASN1##super);\
1890 rb_define_module_function(mASN1, #name, ossl_asn1_##name, -1);\
static int ossl_i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp)
static VALUE decode_enum(unsigned char *der, long length)
VALUE rb_ary_entry(VALUE ary, long offset)
#define ossl_asn1_get_tagging(o)
static ASN1_NULL * obj_to_asn1null(VALUE obj)
static VALUE int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, long *offset, int depth, int yield, int j, int tag, VALUE tc, long *num_read)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
static ossl_asn1_info_t ossl_asn1_info[]
#define ossl_asn1_put_object(pp, cons, len, tag, xc)
static VALUE ossl_asn1obj_get_oid(VALUE self)
#define ossl_str_adjust(str, p)
RUBY_EXTERN VALUE rb_cTime
VALUE rb_ary_each(VALUE array)
VALUE cASN1PrintableString
static ASN1_UTCTIME * obj_to_asn1utime(VALUE time)
static VALUE ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
VALUE rb_ary_push(VALUE ary, VALUE item)
static VALUE ossl_asn1data_to_der(VALUE self)
VALUE asn1str_to_str(ASN1_STRING *str)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_obj_class(VALUE)
#define ossl_asn1_set_value(o, v)
static VALUE ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
void rb_include_module(VALUE klass, VALUE module)
VALUE asn1time_to_time(ASN1_TIME *time)
#define ossl_asn1_get_tag_class(o)
VALUE ossl_membio2str(BIO *bio)
static ASN1_INTEGER * obj_to_asn1int(VALUE obj)
static VALUE decode_bstr(unsigned char *der, long length, long *unused_bits)
static VALUE ossl_asn1obj_get_ln(VALUE self)
void rb_undef_method(VALUE klass, const char *name)
#define ossl_asn1_set_tagging(o, v)
VALUE rb_str_append(VALUE, VALUE)
static VALUE join_der_i(VALUE i, VALUE str)
time_t time_to_time_t(VALUE time)
static void int_ossl_decode_sanity_check(long len, long read, long offset)
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
VALUE ossl_to_der_if_possible(VALUE obj)
#define StringValuePtr(v)
VALUE cASN1UniversalString
#define OSSL_ASN1_DEFINE_CLASS(name, super)
void rb_define_const(VALUE, const char *, VALUE)
static VALUE ossl_asn1_traverse(VALUE self, VALUE obj)
#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass)
void rb_ary_store(VALUE ary, long idx, VALUE val)
static ID sivINFINITE_LENGTH
static VALUE ossl_asn1_decode(VALUE self, VALUE obj)
static int ossl_asn1_tag(VALUE obj)
unsigned char buf[MIME_BUF_SIZE]
static ASN1_STRING * obj_to_asn1str(VALUE obj)
ASN1_TYPE * ossl_asn1_get_asn1type(VALUE obj)
static VALUE decode_obj(unsigned char *der, long length)
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
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)
static VALUE ossl_asn1cons_each(VALUE self)
static ID sCONTEXT_SPECIFIC
static VALUE decode_int(unsigned char *der, long length)
static VALUE class_tag_map
static void ossl_ASN1_TYPE_free(ASN1_TYPE *a)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth, int yield, long *num_read)
VALUE rb_block_call(VALUE, ID, int, VALUE *, VALUE(*)(ANYARGS), VALUE)
void rb_attr(VALUE, ID, int, int, int)
static ASN1_OBJECT * obj_to_asn1obj(VALUE obj)
static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
static VALUE join_der(VALUE enumerable)
VALUE rb_attr_get(VALUE, ID)
#define ossl_asn1_set_tag_class(o, v)
static ASN1_STRING * obj_to_asn1derstr(VALUE obj)
static int ossl_asn1_default_tag(VALUE obj)
void rb_jump_tag(int tag)
static int ossl_asn1_tag_class(VALUE obj)
VALUE rb_define_module_under(VALUE outer, const char *name)
VALUE rb_ivar_set(VALUE, ID, VALUE)
static VALUE ossl_asn1prim_to_der(VALUE self)
#define ossl_asn1_get_infinite_length(o)
static VALUE decode_time(unsigned char *der, long length)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
static VALUE int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, VALUE tc, long *num_read)
static VALUE ossl_asn1cons_to_der(VALUE self)
static VALUE ossl_asn1_decode_all(VALUE self, VALUE obj)
RUBY_EXTERN VALUE rb_cObject
static VALUE decode_eoc(unsigned char *der, long length)
VALUE ossl_buf2str(char *buf, int len)
int ASN1_put_eoc(unsigned char **pp)
#define ossl_asn1_get_value(o)
void ossl_raise(VALUE exc, const char *fmt,...)
static VALUE ossl_asn1_class2sym(int tc)
#define RSTRING_LENINT(str)
VALUE rb_str_new(const char *, long)
#define assert(condition)
static VALUE decode_bool(unsigned char *der, long length)
#define ossl_asn1_get_tag(o)
VALUE rb_obj_alloc(VALUE)
VALUE ossl_bn_new(const BIGNUM *bn)
#define ossl_asn1_set_infinite_length(o, v)
void rb_global_variable(VALUE *)
VALUE cASN1VideotexString
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
void rb_warning(const char *fmt,...)
static ASN1_GENERALIZEDTIME * obj_to_asn1gtime(VALUE time)
VALUE asn1integer_to_num(ASN1_INTEGER *ai)
BIGNUM * GetBNPtr(VALUE obj)
static VALUE ossl_asn1obj_get_sn(VALUE self)
VALUE rb_define_module(const char *name)
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
#define ossl_asn1_object_size(cons, len, tag)
static ASN1_BOOLEAN obj_to_asn1bool(VALUE obj)
static VALUE ossl_asn1eoc_initialize(VALUE self)
static int ossl_asn1_is_explicit(VALUE obj)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE cASN1GeneralizedTime
static VALUE decode_null(unsigned char *der, long length)
VALUE ossl_to_der(VALUE obj)
static ASN1_BIT_STRING * obj_to_asn1bstr(VALUE obj, long unused_bits)
VALUE rb_class_superclass(VALUE)
struct timeval rb_time_timeval(VALUE)
ASN1_INTEGER * num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)