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);
37 if (!time || !time->data)
return Qnil;
38 memset(&tm, 0,
sizeof(
struct tm));
42 if (sscanf((
const char *)time->data,
"%2d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
43 &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
46 if (tm.tm_year < 69) {
52 case V_ASN1_GENERALIZEDTIME:
53 if (sscanf((
const char *)time->data,
"%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
54 &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
89 return rb_str_new((
const char *)str->data, str->length);
96 #define DO_IT_VIA_RUBY 0
109 if (!(bn = ASN1_INTEGER_to_BN(ai,
NULL))) {
113 if (!(txt = BN_bn2dec(bn))) {
141 if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) {
154 if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) {
165 #define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE)
166 #define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
167 #define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
168 #define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
169 #define ossl_asn1_get_infinite_length(o) rb_attr_get((o),sivINFINITE_LENGTH)
171 #define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
172 #define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
173 #define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
174 #define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
175 #define ossl_asn1_set_infinite_length(o,v) rb_ivar_set((o),sivINFINITE_LENGTH,(v))
208 #if OPENSSL_VERSION_NUMBER < 0x00908000L
209 #define ossl_asn1_object_size(cons, len, tag) (cons) == 2 ? (len) + ASN1_object_size((cons), 0, (tag)) : ASN1_object_size((cons), (len), (tag))
210 #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))
212 #define ossl_asn1_object_size(cons, len, tag) ASN1_object_size((cons), (len), (tag))
213 #define ossl_asn1_put_object(pp, cons, len, tag, xc) ASN1_put_object((pp), (cons), (len), (tag), (xc))
222 #if OPENSSL_VERSION_NUMBER < 0x00907000L
223 return RTEST(obj) ? 0xff : 0x100;
225 return RTEST(obj) ? 0xff : 0x0;
235 static ASN1_BIT_STRING*
238 ASN1_BIT_STRING *bstr;
240 if(unused_bits < 0) unused_bits = 0;
242 if(!(bstr = ASN1_BIT_STRING_new()))
245 bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
246 bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07);
257 if(!(str = ASN1_STRING_new()))
271 if(!(null = ASN1_NULL_new()))
284 if(!a1obj) a1obj = OBJ_txt2obj(
RSTRING_PTR(obj), 1);
285 if(!a1obj)
ossl_raise(eASN1Error,
"invalid OBJECT ID");
297 if(!(t = ASN1_UTCTIME_set(
NULL, sec)))
303 static ASN1_GENERALIZEDTIME*
307 ASN1_GENERALIZEDTIME *t;
310 if(!(t =ASN1_GENERALIZEDTIME_set(
NULL, sec)))
323 if(!(a1str = ASN1_STRING_new()))
337 const unsigned char *
p;
340 if((val = d2i_ASN1_BOOLEAN(
NULL, &p, length)) < 0)
350 const unsigned char *
p;
355 if(!(ai = d2i_ASN1_INTEGER(
NULL, &p, length)))
359 ASN1_INTEGER_free(ai);
368 ASN1_BIT_STRING *bstr;
369 const unsigned char *
p;
374 if(!(bstr = d2i_ASN1_BIT_STRING(
NULL, &p, length)))
378 if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
379 *unused_bits = bstr->flags & 0x07;
380 ret =
rb_str_new((
const char *)bstr->data, len);
381 ASN1_BIT_STRING_free(bstr);
390 const unsigned char *
p;
395 if(!(ai = d2i_ASN1_ENUMERATED(
NULL, &p, length)))
399 ASN1_ENUMERATED_free(ai);
409 const unsigned char *
p;
412 if(!(null = d2i_ASN1_NULL(
NULL, &p, length)))
414 ASN1_NULL_free(null);
423 const unsigned char *
p;
429 if(!(obj = d2i_ASN1_OBJECT(
NULL, &p, length)))
431 if((nid = OBJ_obj2nid(obj)) != NID_undef){
432 ASN1_OBJECT_free(obj);
436 if(!(bio = BIO_new(BIO_s_mem()))){
437 ASN1_OBJECT_free(obj);
440 i2a_ASN1_OBJECT(bio, obj);
441 ASN1_OBJECT_free(obj);
452 const unsigned char *
p;
457 if(!(time = d2i_ASN1_TIME(
NULL, &p, length)))
460 (
VALUE)time, &status);
461 ASN1_TIME_free(time);
470 if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00))
491 {
"OBJECT_DESCRIPTOR",
NULL, },
492 {
"EXTERNAL",
NULL, },
495 {
"EMBEDDED_PDV",
NULL, },
497 {
"RELATIVE_OID",
NULL, },
498 {
"[UNIVERSAL 14]",
NULL, },
499 {
"[UNIVERSAL 15]",
NULL, },
513 {
"CHARACTER_STRING",
NULL, },
540 case V_ASN1_ENUMERATED:
542 free_func = ASN1_INTEGER_free;
544 case V_ASN1_BIT_STRING:
548 free_func = ASN1_BIT_STRING_free;
552 free_func = ASN1_NULL_free;
554 case V_ASN1_OCTET_STRING:
555 case V_ASN1_UTF8STRING:
556 case V_ASN1_NUMERICSTRING:
557 case V_ASN1_PRINTABLESTRING:
558 case V_ASN1_T61STRING:
559 case V_ASN1_VIDEOTEXSTRING:
560 case V_ASN1_IA5STRING:
561 case V_ASN1_GRAPHICSTRING:
562 case V_ASN1_ISO64STRING:
563 case V_ASN1_GENERALSTRING:
564 case V_ASN1_UNIVERSALSTRING:
565 case V_ASN1_BMPSTRING:
567 free_func = ASN1_STRING_free;
571 free_func = ASN1_OBJECT_free;
575 free_func = ASN1_TIME_free;
577 case V_ASN1_GENERALIZEDTIME:
579 free_func = ASN1_TIME_free;
582 case V_ASN1_SEQUENCE:
584 free_func = ASN1_STRING_free;
587 ossl_raise(eASN1Error,
"unsupported ASN.1 type");
589 if(!(ret = OPENSSL_malloc(
sizeof(ASN1_TYPE)))){
590 if(free_func) free_func(ptr);
591 ossl_raise(eASN1Error,
"ASN1_TYPE alloc failure");
593 memset(ret, 0,
sizeof(ASN1_TYPE));
594 ASN1_TYPE_set(ret, tag, ptr);
602 VALUE tmp_class, tag;
612 ossl_raise(eASN1Error,
"universal tag for %s not found",
625 ossl_raise(eASN1Error,
"tag number not specified");
637 if(
NIL_P(s))
return 0;
639 if (
SYM2ID(s) == sIMPLICIT)
641 else if (
SYM2ID(s) == sEXPLICIT)
645 ossl_raise(eASN1Error,
"invalid tag default");
658 if(
NIL_P(s)) ret = V_ASN1_UNIVERSAL;
660 if (
SYM2ID(s) == sUNIVERSAL)
661 ret = V_ASN1_UNIVERSAL;
662 else if (
SYM2ID(s) == sAPPLICATION)
663 ret = V_ASN1_APPLICATION;
664 else if (
SYM2ID(s) == sCONTEXT_SPECIFIC)
665 ret = V_ASN1_CONTEXT_SPECIFIC;
666 else if (
SYM2ID(s) == sPRIVATE)
667 ret = V_ASN1_PRIVATE;
679 if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
681 else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
682 return ID2SYM(sCONTEXT_SPECIFIC);
683 else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
684 return ID2SYM(sAPPLICATION);
686 return ID2SYM(sUNIVERSAL);
711 ossl_raise(eASN1Error,
"tag number for Universal too large");
749 VALUE value, der, inf_length;
750 int tag, tag_class, is_cons = 0;
764 if (inf_length ==
Qtrue) {
781 VALUE tc,
long *num_read)
783 VALUE value, asn1data;
789 if(tc == sUNIVERSAL && tag < ossl_asn1_info_size) {
800 case V_ASN1_BIT_STRING:
806 case V_ASN1_ENUMERATED:
813 case V_ASN1_GENERALIZEDTIME:
828 *pp += hlen + length;
829 *num_read = hlen + length;
831 if (tc == sUNIVERSAL && tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
840 if(tag == V_ASN1_BIT_STRING){
854 long *offset,
int depth,
int yield,
int j,
855 int tag,
VALUE tc,
long *num_read)
857 VALUE value, asn1data, ary;
861 infinite = (j == 0x21);
864 while (length > 0 || infinite) {
867 *num_read += inner_read;
868 max_len -= inner_read;
871 length -= inner_read;
880 if (tc == sUNIVERSAL) {
882 int not_sequence_or_set;
884 not_sequence_or_set = tag != V_ASN1_SEQUENCE && tag != V_ASN1_SET;
886 if (not_sequence_or_set) {
891 ossl_raise(eASN1Error,
"invalid non-infinite tag");
921 int yield,
long *num_read)
923 unsigned char *start, *
p;
924 const unsigned char *p0;
925 long len = 0, inner_read = 0, off = *offset;
926 int hlen, tag, tc, j;
927 VALUE asn1data, tag_class;
932 j = ASN1_get_object(&p0, &len, &tag, &tc, length);
933 p = (
unsigned char *)p0;
935 if(len > length)
ossl_raise(eASN1Error,
"value is too short");
936 if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
938 else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
940 else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
959 if(j & V_ASN1_CONSTRUCTED) {
966 if ((j & 0x01) && (len == 0))
ossl_raise(eASN1Error,
"Infinite length for primitive value");
971 *num_read = inner_read;
972 if (len != 0 && inner_read != hlen + len) {
974 "Type mismatch. Bytes read: %ld Bytes available: %ld",
975 inner_read, hlen + len);
985 if (len != 0 && (read != len || offset != len)) {
987 "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
1018 long len, read = 0, offset = 0;
1047 long len, read = 0, offset = 0;
1076 long len, tmp_len = 0, read = 0, offset = 0;
1085 while (tmp_len > 0) {
1090 tmp_len -= tmp_read;
1122 VALUE value, tag, tagging, tag_class;
1124 rb_scan_args(argc, argv,
"13", &value, &tag, &tagging, &tag_class);
1127 ossl_raise(eASN1Error,
"must specify tag number");
1129 ossl_raise(eASN1Error,
"invalid tagging method");
1130 if(
NIL_P(tag_class)) {
1132 tag_class =
ID2SYM(sUNIVERSAL);
1134 tag_class =
ID2SYM(sCONTEXT_SPECIFIC);
1139 ossl_raise(eASN1Error,
"tag number for Universal too large");
1144 tag_class =
ID2SYM(sUNIVERSAL);
1157 VALUE tag, tagging, tag_class, value;
1160 tag_class =
ID2SYM(sUNIVERSAL);
1173 #if OPENSSL_VERSION_NUMBER < 0x00907000L
1175 if(a->type == V_ASN1_BOOLEAN)
1176 return i2d_ASN1_BOOLEAN(a->value.boolean, pp);
1178 return i2d_ASN1_TYPE(a, pp);
1184 #if OPENSSL_VERSION_NUMBER < 0x00907000L
1186 if(a->type == V_ASN1_BOOLEAN){
1204 int tn, tc,
explicit;
1206 unsigned char *
buf, *
p;
1215 if(!(buf = OPENSSL_malloc(len))){
1217 ossl_raise(eASN1Error,
"cannot alloc buffer");
1220 if (tc == V_ASN1_UNIVERSAL) {
1222 }
else if (
explicit) {
1227 *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
1246 int tag, tn, tc,
explicit, constructed = 1;
1247 int found_prim = 0, seq_len;
1250 VALUE value, str, inf_length;
1255 if (inf_length ==
Qtrue) {
1258 if (
CLASS_OF(
self) == cASN1Sequence ||
1265 ossl_raise(eASN1Error,
"Constructive value must be an Array");
1270 while (!found_prim){
1278 ossl_raise(eASN1Error,
"invalid constructed encoding");
1288 if (
CLASS_OF(
self) == cASN1Constructive)
1289 ossl_raise(eASN1Error,
"Constructive shall only be used with infinite length");
1299 if(tc == V_ASN1_UNIVERSAL)
1318 if (
explicit && inf_length ==
Qtrue) {
1394 OBJ_obj2txt(buf,
sizeof(buf), a1obj, 1);
1395 ASN1_OBJECT_free(a1obj);
1400 #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
1401 static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
1402 { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); }
1439 sCONTEXT_SPECIFIC =
rb_intern(
"CONTEXT_SPECIFIC");
1440 sAPPLICATION =
rb_intern(
"APPLICATION");
1449 sivINFINITE_LENGTH =
rb_intern(
"@infinite_length");
1450 sivUNUSED_BITS =
rb_intern(
"@unused_bits");
1596 if(ossl_asn1_info[i].
name[0] ==
'[')
continue;
1872 #define OSSL_ASN1_DEFINE_CLASS(name, super) \
1874 cASN1##name = rb_define_class_under(mASN1, #name, cASN1##super);\
1875 rb_define_module_function(mASN1, #name, ossl_asn1_##name, -1);\