00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "ossl.h"
00012
00013 #if defined(HAVE_SYS_TIME_H)
00014 # include <sys/time.h>
00015 #elif !defined(NT) && !defined(_WIN32)
00016 struct timeval {
00017 long tv_sec;
00018 long tv_usec;
00019 };
00020 #endif
00021
00022 static VALUE join_der(VALUE enumerable);
00023 static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
00024 int depth, int yield, long *num_read);
00025 static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
00026 static VALUE ossl_asn1eoc_initialize(VALUE self);
00027
00028
00029
00030
00031 VALUE
00032 asn1time_to_time(ASN1_TIME *time)
00033 {
00034 struct tm tm;
00035 VALUE argv[6];
00036
00037 if (!time || !time->data) return Qnil;
00038 memset(&tm, 0, sizeof(struct tm));
00039
00040 switch (time->type) {
00041 case V_ASN1_UTCTIME:
00042 if (sscanf((const char *)time->data, "%2d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
00043 &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
00044 ossl_raise(rb_eTypeError, "bad UTCTIME format");
00045 }
00046 if (tm.tm_year < 69) {
00047 tm.tm_year += 2000;
00048 } else {
00049 tm.tm_year += 1900;
00050 }
00051 break;
00052 case V_ASN1_GENERALIZEDTIME:
00053 if (sscanf((const char *)time->data, "%4d%2d%2d%2d%2d%2dZ", &tm.tm_year, &tm.tm_mon,
00054 &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
00055 ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format" );
00056 }
00057 break;
00058 default:
00059 rb_warning("unknown time format");
00060 return Qnil;
00061 }
00062 argv[0] = INT2NUM(tm.tm_year);
00063 argv[1] = INT2NUM(tm.tm_mon);
00064 argv[2] = INT2NUM(tm.tm_mday);
00065 argv[3] = INT2NUM(tm.tm_hour);
00066 argv[4] = INT2NUM(tm.tm_min);
00067 argv[5] = INT2NUM(tm.tm_sec);
00068
00069 return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv);
00070 }
00071
00072
00073
00074
00075 extern struct timeval rb_time_timeval(VALUE);
00076
00077 time_t
00078 time_to_time_t(VALUE time)
00079 {
00080 return (time_t)NUM2LONG(rb_Integer(time));
00081 }
00082
00083
00084
00085
00086 VALUE
00087 asn1str_to_str(ASN1_STRING *str)
00088 {
00089 return rb_str_new((const char *)str->data, str->length);
00090 }
00091
00092
00093
00094
00095
00096 #define DO_IT_VIA_RUBY 0
00097 VALUE
00098 asn1integer_to_num(ASN1_INTEGER *ai)
00099 {
00100 BIGNUM *bn;
00101 #if DO_IT_VIA_RUBY
00102 char *txt;
00103 #endif
00104 VALUE num;
00105
00106 if (!ai) {
00107 ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!");
00108 }
00109 if (!(bn = ASN1_INTEGER_to_BN(ai, NULL))) {
00110 ossl_raise(eOSSLError, NULL);
00111 }
00112 #if DO_IT_VIA_RUBY
00113 if (!(txt = BN_bn2dec(bn))) {
00114 BN_free(bn);
00115 ossl_raise(eOSSLError, NULL);
00116 }
00117 num = rb_cstr_to_inum(txt, 10, Qtrue);
00118 OPENSSL_free(txt);
00119 #else
00120 num = ossl_bn_new(bn);
00121 #endif
00122 BN_free(bn);
00123
00124 return num;
00125 }
00126
00127 #if DO_IT_VIA_RUBY
00128 ASN1_INTEGER *
00129 num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
00130 {
00131 BIGNUM *bn = NULL;
00132
00133 if (RTEST(rb_obj_is_kind_of(obj, cBN))) {
00134 bn = GetBNPtr(obj);
00135 } else {
00136 obj = rb_String(obj);
00137 if (!BN_dec2bn(&bn, StringValuePtr(obj))) {
00138 ossl_raise(eOSSLError, NULL);
00139 }
00140 }
00141 if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) {
00142 BN_free(bn);
00143 ossl_raise(eOSSLError, NULL);
00144 }
00145 BN_free(bn);
00146 return ai;
00147 }
00148 #else
00149 ASN1_INTEGER *
00150 num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
00151 {
00152 BIGNUM *bn;
00153
00154 if (NIL_P(obj))
00155 ossl_raise(rb_eTypeError, "Can't convert nil into Integer");
00156
00157 bn = GetBNPtr(obj);
00158
00159 if (!(ai = BN_to_ASN1_INTEGER(bn, ai)))
00160 ossl_raise(eOSSLError, NULL);
00161
00162 return ai;
00163 }
00164 #endif
00165
00166
00167
00168
00169
00170 #define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE)
00171 #define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
00172 #define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
00173 #define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
00174 #define ossl_asn1_get_infinite_length(o) rb_attr_get((o),sivINFINITE_LENGTH)
00175
00176 #define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
00177 #define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
00178 #define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
00179 #define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
00180 #define ossl_asn1_set_infinite_length(o,v) rb_ivar_set((o),sivINFINITE_LENGTH,(v))
00181
00182 VALUE mASN1;
00183 VALUE eASN1Error;
00184
00185 VALUE cASN1Data;
00186 VALUE cASN1Primitive;
00187 VALUE cASN1Constructive;
00188
00189 VALUE cASN1EndOfContent;
00190 VALUE cASN1Boolean;
00191 VALUE cASN1Integer, cASN1Enumerated;
00192 VALUE cASN1BitString;
00193 VALUE cASN1OctetString, cASN1UTF8String;
00194 VALUE cASN1NumericString, cASN1PrintableString;
00195 VALUE cASN1T61String, cASN1VideotexString;
00196 VALUE cASN1IA5String, cASN1GraphicString;
00197 VALUE cASN1ISO64String, cASN1GeneralString;
00198 VALUE cASN1UniversalString, cASN1BMPString;
00199 VALUE cASN1Null;
00200 VALUE cASN1ObjectId;
00201 VALUE cASN1UTCTime, cASN1GeneralizedTime;
00202 VALUE cASN1Sequence, cASN1Set;
00203
00204 static ID sIMPLICIT, sEXPLICIT;
00205 static ID sUNIVERSAL, sAPPLICATION, sCONTEXT_SPECIFIC, sPRIVATE;
00206 static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINFINITE_LENGTH, sivUNUSED_BITS;
00207
00208
00209
00210
00211
00212
00213 #if OPENSSL_VERSION_NUMBER < 0x00908000L
00214 #define ossl_asn1_object_size(cons, len, tag) (cons) == 2 ? (len) + ASN1_object_size((cons), 0, (tag)) : ASN1_object_size((cons), (len), (tag))
00215 #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))
00216 #else
00217 #define ossl_asn1_object_size(cons, len, tag) ASN1_object_size((cons), (len), (tag))
00218 #define ossl_asn1_put_object(pp, cons, len, tag, xc) ASN1_put_object((pp), (cons), (len), (tag), (xc))
00219 #endif
00220
00221
00222
00223
00224 static ASN1_BOOLEAN
00225 obj_to_asn1bool(VALUE obj)
00226 {
00227 if (NIL_P(obj))
00228 ossl_raise(rb_eTypeError, "Can't convert nil into Boolean");
00229
00230 #if OPENSSL_VERSION_NUMBER < 0x00907000L
00231 return RTEST(obj) ? 0xff : 0x100;
00232 #else
00233 return RTEST(obj) ? 0xff : 0x0;
00234 #endif
00235 }
00236
00237 static ASN1_INTEGER*
00238 obj_to_asn1int(VALUE obj)
00239 {
00240 return num_to_asn1integer(obj, NULL);
00241 }
00242
00243 static ASN1_BIT_STRING*
00244 obj_to_asn1bstr(VALUE obj, long unused_bits)
00245 {
00246 ASN1_BIT_STRING *bstr;
00247
00248 if(unused_bits < 0) unused_bits = 0;
00249 StringValue(obj);
00250 if(!(bstr = ASN1_BIT_STRING_new()))
00251 ossl_raise(eASN1Error, NULL);
00252 ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj));
00253 bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
00254 bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07);
00255
00256 return bstr;
00257 }
00258
00259 static ASN1_STRING*
00260 obj_to_asn1str(VALUE obj)
00261 {
00262 ASN1_STRING *str;
00263
00264 StringValue(obj);
00265 if(!(str = ASN1_STRING_new()))
00266 ossl_raise(eASN1Error, NULL);
00267 ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj));
00268
00269 return str;
00270 }
00271
00272 static ASN1_NULL*
00273 obj_to_asn1null(VALUE obj)
00274 {
00275 ASN1_NULL *null;
00276
00277 if(!NIL_P(obj))
00278 ossl_raise(eASN1Error, "nil expected");
00279 if(!(null = ASN1_NULL_new()))
00280 ossl_raise(eASN1Error, NULL);
00281
00282 return null;
00283 }
00284
00285 static ASN1_OBJECT*
00286 obj_to_asn1obj(VALUE obj)
00287 {
00288 ASN1_OBJECT *a1obj;
00289
00290 StringValue(obj);
00291 a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 0);
00292 if(!a1obj) a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 1);
00293 if(!a1obj) ossl_raise(eASN1Error, "invalid OBJECT ID");
00294
00295 return a1obj;
00296 }
00297
00298 static ASN1_UTCTIME*
00299 obj_to_asn1utime(VALUE time)
00300 {
00301 time_t sec;
00302 ASN1_UTCTIME *t;
00303
00304 sec = time_to_time_t(time);
00305 if(!(t = ASN1_UTCTIME_set(NULL, sec)))
00306 ossl_raise(eASN1Error, NULL);
00307
00308 return t;
00309 }
00310
00311 static ASN1_GENERALIZEDTIME*
00312 obj_to_asn1gtime(VALUE time)
00313 {
00314 time_t sec;
00315 ASN1_GENERALIZEDTIME *t;
00316
00317 sec = time_to_time_t(time);
00318 if(!(t =ASN1_GENERALIZEDTIME_set(NULL, sec)))
00319 ossl_raise(eASN1Error, NULL);
00320
00321 return t;
00322 }
00323
00324 static ASN1_STRING*
00325 obj_to_asn1derstr(VALUE obj)
00326 {
00327 ASN1_STRING *a1str;
00328 VALUE str;
00329
00330 str = ossl_to_der(obj);
00331 if(!(a1str = ASN1_STRING_new()))
00332 ossl_raise(eASN1Error, NULL);
00333 ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str));
00334
00335 return a1str;
00336 }
00337
00338
00339
00340
00341 static VALUE
00342 decode_bool(unsigned char* der, int length)
00343 {
00344 int val;
00345 const unsigned char *p;
00346
00347 p = der;
00348 if((val = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0)
00349 ossl_raise(eASN1Error, NULL);
00350
00351 return val ? Qtrue : Qfalse;
00352 }
00353
00354 static VALUE
00355 decode_int(unsigned char* der, int length)
00356 {
00357 ASN1_INTEGER *ai;
00358 const unsigned char *p;
00359 VALUE ret;
00360 int status = 0;
00361
00362 p = der;
00363 if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length)))
00364 ossl_raise(eASN1Error, NULL);
00365 ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num,
00366 (VALUE)ai, &status);
00367 ASN1_INTEGER_free(ai);
00368 if(status) rb_jump_tag(status);
00369
00370 return ret;
00371 }
00372
00373 static VALUE
00374 decode_bstr(unsigned char* der, int length, long *unused_bits)
00375 {
00376 ASN1_BIT_STRING *bstr;
00377 const unsigned char *p;
00378 long len;
00379 VALUE ret;
00380
00381 p = der;
00382 if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
00383 ossl_raise(eASN1Error, NULL);
00384 len = bstr->length;
00385 *unused_bits = 0;
00386 if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
00387 *unused_bits = bstr->flags & 0x07;
00388 ret = rb_str_new((const char *)bstr->data, len);
00389 ASN1_BIT_STRING_free(bstr);
00390
00391 return ret;
00392 }
00393
00394 static VALUE
00395 decode_enum(unsigned char* der, int length)
00396 {
00397 ASN1_ENUMERATED *ai;
00398 const unsigned char *p;
00399 VALUE ret;
00400 int status = 0;
00401
00402 p = der;
00403 if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length)))
00404 ossl_raise(eASN1Error, NULL);
00405 ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num,
00406 (VALUE)ai, &status);
00407 ASN1_ENUMERATED_free(ai);
00408 if(status) rb_jump_tag(status);
00409
00410 return ret;
00411 }
00412
00413 static VALUE
00414 decode_null(unsigned char* der, int length)
00415 {
00416 ASN1_NULL *null;
00417 const unsigned char *p;
00418
00419 p = der;
00420 if(!(null = d2i_ASN1_NULL(NULL, &p, length)))
00421 ossl_raise(eASN1Error, NULL);
00422 ASN1_NULL_free(null);
00423
00424 return Qnil;
00425 }
00426
00427 static VALUE
00428 decode_obj(unsigned char* der, int length)
00429 {
00430 ASN1_OBJECT *obj;
00431 const unsigned char *p;
00432 VALUE ret;
00433 int nid;
00434 BIO *bio;
00435
00436 p = der;
00437 if(!(obj = d2i_ASN1_OBJECT(NULL, &p, length)))
00438 ossl_raise(eASN1Error, NULL);
00439 if((nid = OBJ_obj2nid(obj)) != NID_undef){
00440 ASN1_OBJECT_free(obj);
00441 ret = rb_str_new2(OBJ_nid2sn(nid));
00442 }
00443 else{
00444 if(!(bio = BIO_new(BIO_s_mem()))){
00445 ASN1_OBJECT_free(obj);
00446 ossl_raise(eASN1Error, NULL);
00447 }
00448 i2a_ASN1_OBJECT(bio, obj);
00449 ASN1_OBJECT_free(obj);
00450 ret = ossl_membio2str(bio);
00451 }
00452
00453 return ret;
00454 }
00455
00456 static VALUE
00457 decode_time(unsigned char* der, int length)
00458 {
00459 ASN1_TIME *time;
00460 const unsigned char *p;
00461 VALUE ret;
00462 int status = 0;
00463
00464 p = der;
00465 if(!(time = d2i_ASN1_TIME(NULL, &p, length)))
00466 ossl_raise(eASN1Error, NULL);
00467 ret = rb_protect((VALUE(*)_((VALUE)))asn1time_to_time,
00468 (VALUE)time, &status);
00469 ASN1_TIME_free(time);
00470 if(status) rb_jump_tag(status);
00471
00472 return ret;
00473 }
00474
00475 static VALUE
00476 decode_eoc(unsigned char *der, int length)
00477 {
00478 if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00))
00479 ossl_raise(eASN1Error, NULL);
00480
00481 return rb_str_new("", 0);
00482 }
00483
00484
00485
00486 typedef struct {
00487 const char *name;
00488 VALUE *klass;
00489 } ossl_asn1_info_t;
00490
00491 static ossl_asn1_info_t ossl_asn1_info[] = {
00492 { "EOC", &cASN1EndOfContent, },
00493 { "BOOLEAN", &cASN1Boolean, },
00494 { "INTEGER", &cASN1Integer, },
00495 { "BIT_STRING", &cASN1BitString, },
00496 { "OCTET_STRING", &cASN1OctetString, },
00497 { "NULL", &cASN1Null, },
00498 { "OBJECT", &cASN1ObjectId, },
00499 { "OBJECT_DESCRIPTOR", NULL, },
00500 { "EXTERNAL", NULL, },
00501 { "REAL", NULL, },
00502 { "ENUMERATED", &cASN1Enumerated, },
00503 { "EMBEDDED_PDV", NULL, },
00504 { "UTF8STRING", &cASN1UTF8String, },
00505 { "RELATIVE_OID", NULL, },
00506 { "[UNIVERSAL 14]", NULL, },
00507 { "[UNIVERSAL 15]", NULL, },
00508 { "SEQUENCE", &cASN1Sequence, },
00509 { "SET", &cASN1Set, },
00510 { "NUMERICSTRING", &cASN1NumericString, },
00511 { "PRINTABLESTRING", &cASN1PrintableString, },
00512 { "T61STRING", &cASN1T61String, },
00513 { "VIDEOTEXSTRING", &cASN1VideotexString, },
00514 { "IA5STRING", &cASN1IA5String, },
00515 { "UTCTIME", &cASN1UTCTime, },
00516 { "GENERALIZEDTIME", &cASN1GeneralizedTime, },
00517 { "GRAPHICSTRING", &cASN1GraphicString, },
00518 { "ISO64STRING", &cASN1ISO64String, },
00519 { "GENERALSTRING", &cASN1GeneralString, },
00520 { "UNIVERSALSTRING", &cASN1UniversalString, },
00521 { "CHARACTER_STRING", NULL, },
00522 { "BMPSTRING", &cASN1BMPString, },
00523 };
00524
00525 int ossl_asn1_info_size = (sizeof(ossl_asn1_info)/sizeof(ossl_asn1_info[0]));
00526
00527 static VALUE class_tag_map;
00528
00529 static int ossl_asn1_default_tag(VALUE obj);
00530
00531 ASN1_TYPE*
00532 ossl_asn1_get_asn1type(VALUE obj)
00533 {
00534 ASN1_TYPE *ret;
00535 VALUE value, rflag;
00536 void *ptr;
00537 void (*free_func)();
00538 int tag, flag;
00539
00540 tag = ossl_asn1_default_tag(obj);
00541 value = ossl_asn1_get_value(obj);
00542 switch(tag){
00543 case V_ASN1_BOOLEAN:
00544 ptr = (void*)(VALUE)obj_to_asn1bool(value);
00545 free_func = NULL;
00546 break;
00547 case V_ASN1_INTEGER:
00548 case V_ASN1_ENUMERATED:
00549 ptr = obj_to_asn1int(value);
00550 free_func = ASN1_INTEGER_free;
00551 break;
00552 case V_ASN1_BIT_STRING:
00553 rflag = rb_attr_get(obj, sivUNUSED_BITS);
00554 flag = NIL_P(rflag) ? -1 : NUM2INT(rflag);
00555 ptr = obj_to_asn1bstr(value, flag);
00556 free_func = ASN1_BIT_STRING_free;
00557 break;
00558 case V_ASN1_NULL:
00559 ptr = obj_to_asn1null(value);
00560 free_func = ASN1_NULL_free;
00561 break;
00562 case V_ASN1_OCTET_STRING:
00563 case V_ASN1_UTF8STRING:
00564 case V_ASN1_NUMERICSTRING:
00565 case V_ASN1_PRINTABLESTRING:
00566 case V_ASN1_T61STRING:
00567 case V_ASN1_VIDEOTEXSTRING:
00568 case V_ASN1_IA5STRING:
00569 case V_ASN1_GRAPHICSTRING:
00570 case V_ASN1_ISO64STRING:
00571 case V_ASN1_GENERALSTRING:
00572 case V_ASN1_UNIVERSALSTRING:
00573 case V_ASN1_BMPSTRING:
00574 ptr = obj_to_asn1str(value);
00575 free_func = ASN1_STRING_free;
00576 break;
00577 case V_ASN1_OBJECT:
00578 ptr = obj_to_asn1obj(value);
00579 free_func = ASN1_OBJECT_free;
00580 break;
00581 case V_ASN1_UTCTIME:
00582 ptr = obj_to_asn1utime(value);
00583 free_func = ASN1_TIME_free;
00584 break;
00585 case V_ASN1_GENERALIZEDTIME:
00586 ptr = obj_to_asn1gtime(value);
00587 free_func = ASN1_TIME_free;
00588 break;
00589 case V_ASN1_SET:
00590 case V_ASN1_SEQUENCE:
00591 ptr = obj_to_asn1derstr(obj);
00592 free_func = ASN1_STRING_free;
00593 break;
00594 default:
00595 ossl_raise(eASN1Error, "unsupported ASN.1 type");
00596 }
00597 if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){
00598 if(free_func) free_func(ptr);
00599 ossl_raise(eASN1Error, "ASN1_TYPE alloc failure");
00600 }
00601 memset(ret, 0, sizeof(ASN1_TYPE));
00602 ASN1_TYPE_set(ret, tag, ptr);
00603
00604 return ret;
00605 }
00606
00607 static int
00608 ossl_asn1_default_tag(VALUE obj)
00609 {
00610 VALUE tmp_class, tag;
00611
00612 tmp_class = CLASS_OF(obj);
00613 while (tmp_class) {
00614 tag = rb_hash_lookup(class_tag_map, tmp_class);
00615 if (tag != Qnil) {
00616 return NUM2INT(tag);
00617 }
00618 tmp_class = rb_class_superclass(tmp_class);
00619 }
00620 ossl_raise(eASN1Error, "universal tag for %s not found",
00621 rb_class2name(CLASS_OF(obj)));
00622
00623 return -1;
00624 }
00625
00626 static int
00627 ossl_asn1_tag(VALUE obj)
00628 {
00629 VALUE tag;
00630
00631 tag = ossl_asn1_get_tag(obj);
00632 if(NIL_P(tag))
00633 ossl_raise(eASN1Error, "tag number not specified");
00634
00635 return NUM2INT(tag);
00636 }
00637
00638 static int
00639 ossl_asn1_is_explicit(VALUE obj)
00640 {
00641 VALUE s;
00642 int ret = -1;
00643
00644 s = ossl_asn1_get_tagging(obj);
00645 if(NIL_P(s)) return 0;
00646 else if(SYMBOL_P(s)){
00647 if (SYM2ID(s) == sIMPLICIT)
00648 ret = 0;
00649 else if (SYM2ID(s) == sEXPLICIT)
00650 ret = 1;
00651 }
00652 if(ret < 0){
00653 ossl_raise(eASN1Error, "invalid tag default");
00654 }
00655
00656 return ret;
00657 }
00658
00659 static int
00660 ossl_asn1_tag_class(VALUE obj)
00661 {
00662 VALUE s;
00663 int ret = -1;
00664
00665 s = ossl_asn1_get_tag_class(obj);
00666 if(NIL_P(s)) ret = V_ASN1_UNIVERSAL;
00667 else if(SYMBOL_P(s)){
00668 if (SYM2ID(s) == sUNIVERSAL)
00669 ret = V_ASN1_UNIVERSAL;
00670 else if (SYM2ID(s) == sAPPLICATION)
00671 ret = V_ASN1_APPLICATION;
00672 else if (SYM2ID(s) == sCONTEXT_SPECIFIC)
00673 ret = V_ASN1_CONTEXT_SPECIFIC;
00674 else if (SYM2ID(s) == sPRIVATE)
00675 ret = V_ASN1_PRIVATE;
00676 }
00677 if(ret < 0){
00678 ossl_raise(eASN1Error, "invalid tag class");
00679 }
00680
00681 return ret;
00682 }
00683
00684 static VALUE
00685 ossl_asn1_class2sym(int tc)
00686 {
00687 if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
00688 return ID2SYM(sPRIVATE);
00689 else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
00690 return ID2SYM(sCONTEXT_SPECIFIC);
00691 else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
00692 return ID2SYM(sAPPLICATION);
00693 else
00694 return ID2SYM(sUNIVERSAL);
00695 }
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 static VALUE
00714 ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
00715 {
00716 if(!SYMBOL_P(tag_class))
00717 ossl_raise(eASN1Error, "invalid tag class");
00718 if((SYM2ID(tag_class) == sUNIVERSAL) && NUM2INT(tag) > 31)
00719 ossl_raise(eASN1Error, "tag number for Universal too large");
00720 ossl_asn1_set_tag(self, tag);
00721 ossl_asn1_set_value(self, value);
00722 ossl_asn1_set_tag_class(self, tag_class);
00723 ossl_asn1_set_infinite_length(self, Qfalse);
00724
00725 return self;
00726 }
00727
00728 static VALUE
00729 join_der_i(VALUE i, VALUE str)
00730 {
00731 i = ossl_to_der_if_possible(i);
00732 StringValue(i);
00733 rb_str_append(str, i);
00734 return Qnil;
00735 }
00736
00737 static VALUE
00738 join_der(VALUE enumerable)
00739 {
00740 VALUE str = rb_str_new(0, 0);
00741 rb_block_call(enumerable, rb_intern("each"), 0, 0, join_der_i, str);
00742 return str;
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 static VALUE
00755 ossl_asn1data_to_der(VALUE self)
00756 {
00757 VALUE value, der, inf_length;
00758 int tag, tag_class, is_cons = 0;
00759 long length;
00760 unsigned char *p;
00761
00762 value = ossl_asn1_get_value(self);
00763 if(rb_obj_is_kind_of(value, rb_cArray)){
00764 is_cons = 1;
00765 value = join_der(value);
00766 }
00767 StringValue(value);
00768
00769 tag = ossl_asn1_tag(self);
00770 tag_class = ossl_asn1_tag_class(self);
00771 inf_length = ossl_asn1_get_infinite_length(self);
00772 if (inf_length == Qtrue) {
00773 is_cons = 2;
00774 }
00775 if((length = ossl_asn1_object_size(is_cons, RSTRING_LENINT(value), tag)) <= 0)
00776 ossl_raise(eASN1Error, NULL);
00777 der = rb_str_new(0, length);
00778 p = (unsigned char *)RSTRING_PTR(der);
00779 ossl_asn1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class);
00780 memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
00781 p += RSTRING_LEN(value);
00782 ossl_str_adjust(der, p);
00783
00784 return der;
00785 }
00786
00787 static VALUE
00788 int_ossl_asn1_decode0_prim(unsigned char **pp, long length, int hlen, int tag,
00789 VALUE tc, long *num_read)
00790 {
00791 VALUE value, asn1data;
00792 unsigned char *p;
00793 long flag = 0;
00794
00795 p = *pp;
00796
00797 if(tc == sUNIVERSAL && tag < ossl_asn1_info_size) {
00798 switch(tag){
00799 case V_ASN1_EOC:
00800 value = decode_eoc(p, hlen+length);
00801 break;
00802 case V_ASN1_BOOLEAN:
00803 value = decode_bool(p, hlen+length);
00804 break;
00805 case V_ASN1_INTEGER:
00806 value = decode_int(p, hlen+length);
00807 break;
00808 case V_ASN1_BIT_STRING:
00809 value = decode_bstr(p, hlen+length, &flag);
00810 break;
00811 case V_ASN1_NULL:
00812 value = decode_null(p, hlen+length);
00813 break;
00814 case V_ASN1_ENUMERATED:
00815 value = decode_enum(p, hlen+length);
00816 break;
00817 case V_ASN1_OBJECT:
00818 value = decode_obj(p, hlen+length);
00819 break;
00820 case V_ASN1_UTCTIME:
00821 case V_ASN1_GENERALIZEDTIME:
00822 value = decode_time(p, hlen+length);
00823 break;
00824 default:
00825
00826 p += hlen;
00827 value = rb_str_new((const char *)p, length);
00828 break;
00829 }
00830 }
00831 else {
00832 p += hlen;
00833 value = rb_str_new((const char *)p, length);
00834 }
00835
00836 *pp += hlen + length;
00837 *num_read = hlen + length;
00838
00839 if (tc == sUNIVERSAL && tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
00840 VALUE klass = *ossl_asn1_info[tag].klass;
00841 VALUE args[4];
00842 args[0] = value;
00843 args[1] = INT2NUM(tag);
00844 args[2] = Qnil;
00845 args[3] = ID2SYM(tc);
00846 asn1data = rb_obj_alloc(klass);
00847 ossl_asn1_initialize(4, args, asn1data);
00848 if(tag == V_ASN1_BIT_STRING){
00849 rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag));
00850 }
00851 }
00852 else {
00853 asn1data = rb_obj_alloc(cASN1Data);
00854 ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), ID2SYM(tc));
00855 }
00856
00857 return asn1data;
00858 }
00859
00860 static VALUE
00861 int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
00862 long *offset, int depth, int yield, int j,
00863 int tag, VALUE tc, long *num_read)
00864 {
00865 VALUE value, asn1data, ary;
00866 int infinite;
00867 long off = *offset;
00868
00869 infinite = (j == 0x21);
00870 ary = rb_ary_new();
00871
00872 while (length > 0 || infinite) {
00873 long inner_read = 0;
00874 value = ossl_asn1_decode0(pp, max_len, &off, depth + 1, yield, &inner_read);
00875 *num_read += inner_read;
00876 max_len -= inner_read;
00877 rb_ary_push(ary, value);
00878 if (length > 0)
00879 length -= inner_read;
00880
00881 if (infinite &&
00882 NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC &&
00883 SYM2ID(ossl_asn1_get_tag_class(value)) == sUNIVERSAL) {
00884 break;
00885 }
00886 }
00887
00888 if (tc == sUNIVERSAL) {
00889 VALUE args[4];
00890 int not_sequence_or_set;
00891
00892 not_sequence_or_set = tag != V_ASN1_SEQUENCE && tag != V_ASN1_SET;
00893
00894 if (not_sequence_or_set) {
00895 if (infinite) {
00896 asn1data = rb_obj_alloc(cASN1Constructive);
00897 }
00898 else {
00899 ossl_raise(eASN1Error, "invalid non-infinite tag");
00900 return Qnil;
00901 }
00902 }
00903 else {
00904 VALUE klass = *ossl_asn1_info[tag].klass;
00905 asn1data = rb_obj_alloc(klass);
00906 }
00907 args[0] = ary;
00908 args[1] = INT2NUM(tag);
00909 args[2] = Qnil;
00910 args[3] = ID2SYM(tc);
00911 ossl_asn1_initialize(4, args, asn1data);
00912 }
00913 else {
00914 asn1data = rb_obj_alloc(cASN1Data);
00915 ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), ID2SYM(tc));
00916 }
00917
00918 if (infinite)
00919 ossl_asn1_set_infinite_length(asn1data, Qtrue);
00920 else
00921 ossl_asn1_set_infinite_length(asn1data, Qfalse);
00922
00923 *offset = off;
00924 return asn1data;
00925 }
00926
00927 static VALUE
00928 ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
00929 int yield, long *num_read)
00930 {
00931 unsigned char *start, *p;
00932 const unsigned char *p0;
00933 long len = 0, inner_read = 0, off = *offset;
00934 int hlen, tag, tc, j;
00935 VALUE asn1data, tag_class;
00936
00937 p = *pp;
00938 start = p;
00939 p0 = p;
00940 j = ASN1_get_object(&p0, &len, &tag, &tc, length);
00941 p = (unsigned char *)p0;
00942 if(j & 0x80) ossl_raise(eASN1Error, NULL);
00943 if(len > length) ossl_raise(eASN1Error, "value is too short");
00944 if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
00945 tag_class = sPRIVATE;
00946 else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
00947 tag_class = sCONTEXT_SPECIFIC;
00948 else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
00949 tag_class = sAPPLICATION;
00950 else
00951 tag_class = sUNIVERSAL;
00952
00953 hlen = p - start;
00954
00955 if(yield) {
00956 VALUE arg = rb_ary_new();
00957 rb_ary_push(arg, LONG2NUM(depth));
00958 rb_ary_push(arg, LONG2NUM(*offset));
00959 rb_ary_push(arg, LONG2NUM(hlen));
00960 rb_ary_push(arg, LONG2NUM(len));
00961 rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse);
00962 rb_ary_push(arg, ossl_asn1_class2sym(tc));
00963 rb_ary_push(arg, INT2NUM(tag));
00964 rb_yield(arg);
00965 }
00966
00967 if(j & V_ASN1_CONSTRUCTED) {
00968 *pp += hlen;
00969 off += hlen;
00970 asn1data = int_ossl_asn1_decode0_cons(pp, length, len, &off, depth, yield, j, tag, tag_class, &inner_read);
00971 inner_read += hlen;
00972 }
00973 else {
00974 if ((j & 0x01) && (len == 0)) ossl_raise(eASN1Error, "Infinite length for primitive value");
00975 asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read);
00976 off += hlen + len;
00977 }
00978 if (num_read)
00979 *num_read = inner_read;
00980 if (len != 0 && inner_read != hlen + len) {
00981 ossl_raise(eASN1Error,
00982 "Type mismatch. Bytes read: %ld Bytes available: %ld",
00983 inner_read, hlen + len);
00984 }
00985
00986 *offset = off;
00987 return asn1data;
00988 }
00989
00990 static void
00991 int_ossl_decode_sanity_check(long len, long read, long offset)
00992 {
00993 if (len != 0 && (read != len || offset != len)) {
00994 ossl_raise(eASN1Error,
00995 "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld",
00996 read, len, offset);
00997 }
00998 }
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021 static VALUE
01022 ossl_asn1_traverse(VALUE self, VALUE obj)
01023 {
01024 unsigned char *p;
01025 volatile VALUE tmp;
01026 long len, read = 0, offset = 0;
01027
01028 obj = ossl_to_der_if_possible(obj);
01029 tmp = rb_str_new4(StringValue(obj));
01030 p = (unsigned char *)RSTRING_PTR(tmp);
01031 len = RSTRING_LEN(tmp);
01032 ossl_asn1_decode0(&p, len, &offset, 0, 1, &read);
01033 int_ossl_decode_sanity_check(len, read, offset);
01034 return Qnil;
01035 }
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 static VALUE
01050 ossl_asn1_decode(VALUE self, VALUE obj)
01051 {
01052 VALUE ret;
01053 unsigned char *p;
01054 volatile VALUE tmp;
01055 long len, read = 0, offset = 0;
01056
01057 obj = ossl_to_der_if_possible(obj);
01058 tmp = rb_str_new4(StringValue(obj));
01059 p = (unsigned char *)RSTRING_PTR(tmp);
01060 len = RSTRING_LEN(tmp);
01061 ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read);
01062 int_ossl_decode_sanity_check(len, read, offset);
01063 return ret;
01064 }
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 static VALUE
01080 ossl_asn1_decode_all(VALUE self, VALUE obj)
01081 {
01082 VALUE ary, val;
01083 unsigned char *p;
01084 long len, tmp_len = 0, read = 0, offset = 0;
01085 volatile VALUE tmp;
01086
01087 obj = ossl_to_der_if_possible(obj);
01088 tmp = rb_str_new4(StringValue(obj));
01089 p = (unsigned char *)RSTRING_PTR(tmp);
01090 len = RSTRING_LEN(tmp);
01091 tmp_len = len;
01092 ary = rb_ary_new();
01093 while (tmp_len > 0) {
01094 long tmp_read = 0;
01095 val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read);
01096 rb_ary_push(ary, val);
01097 read += tmp_read;
01098 tmp_len -= tmp_read;
01099 }
01100 int_ossl_decode_sanity_check(len, read, offset);
01101 return ary;
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 static VALUE
01128 ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
01129 {
01130 VALUE value, tag, tagging, tag_class;
01131
01132 rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
01133 if(argc > 1){
01134 if(NIL_P(tag))
01135 ossl_raise(eASN1Error, "must specify tag number");
01136 if(!NIL_P(tagging) && !SYMBOL_P(tagging))
01137 ossl_raise(eASN1Error, "invalid tagging method");
01138 if(NIL_P(tag_class)) {
01139 if (NIL_P(tagging))
01140 tag_class = ID2SYM(sUNIVERSAL);
01141 else
01142 tag_class = ID2SYM(sCONTEXT_SPECIFIC);
01143 }
01144 if(!SYMBOL_P(tag_class))
01145 ossl_raise(eASN1Error, "invalid tag class");
01146 if(SYM2ID(tagging) == sIMPLICIT && NUM2INT(tag) > 31)
01147 ossl_raise(eASN1Error, "tag number for Universal too large");
01148 }
01149 else{
01150 tag = INT2NUM(ossl_asn1_default_tag(self));
01151 tagging = Qnil;
01152 tag_class = ID2SYM(sUNIVERSAL);
01153 }
01154 ossl_asn1_set_tag(self, tag);
01155 ossl_asn1_set_value(self, value);
01156 ossl_asn1_set_tagging(self, tagging);
01157 ossl_asn1_set_tag_class(self, tag_class);
01158 ossl_asn1_set_infinite_length(self, Qfalse);
01159
01160 return self;
01161 }
01162
01163 static VALUE
01164 ossl_asn1eoc_initialize(VALUE self) {
01165 VALUE tag, tagging, tag_class, value;
01166 tag = INT2NUM(ossl_asn1_default_tag(self));
01167 tagging = Qnil;
01168 tag_class = ID2SYM(sUNIVERSAL);
01169 value = rb_str_new("", 0);
01170 ossl_asn1_set_tag(self, tag);
01171 ossl_asn1_set_value(self, value);
01172 ossl_asn1_set_tagging(self, tagging);
01173 ossl_asn1_set_tag_class(self, tag_class);
01174 ossl_asn1_set_infinite_length(self, Qfalse);
01175 return self;
01176 }
01177
01178 static int
01179 ossl_i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp)
01180 {
01181 #if OPENSSL_VERSION_NUMBER < 0x00907000L
01182 if(!a) return 0;
01183 if(a->type == V_ASN1_BOOLEAN)
01184 return i2d_ASN1_BOOLEAN(a->value.boolean, pp);
01185 #endif
01186 return i2d_ASN1_TYPE(a, pp);
01187 }
01188
01189 static void
01190 ossl_ASN1_TYPE_free(ASN1_TYPE *a)
01191 {
01192 #if OPENSSL_VERSION_NUMBER < 0x00907000L
01193 if(!a) return;
01194 if(a->type == V_ASN1_BOOLEAN){
01195 OPENSSL_free(a);
01196 return;
01197 }
01198 #endif
01199 ASN1_TYPE_free(a);
01200 }
01201
01202
01203
01204
01205
01206
01207
01208 static VALUE
01209 ossl_asn1prim_to_der(VALUE self)
01210 {
01211 ASN1_TYPE *asn1;
01212 int tn, tc, explicit;
01213 long len, reallen;
01214 unsigned char *buf, *p;
01215 VALUE str;
01216
01217 tn = NUM2INT(ossl_asn1_get_tag(self));
01218 tc = ossl_asn1_tag_class(self);
01219 explicit = ossl_asn1_is_explicit(self);
01220 asn1 = ossl_asn1_get_asn1type(self);
01221
01222 len = ossl_asn1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn);
01223 if(!(buf = OPENSSL_malloc(len))){
01224 ossl_ASN1_TYPE_free(asn1);
01225 ossl_raise(eASN1Error, "cannot alloc buffer");
01226 }
01227 p = buf;
01228 if (tc == V_ASN1_UNIVERSAL) {
01229 ossl_i2d_ASN1_TYPE(asn1, &p);
01230 } else if (explicit) {
01231 ossl_asn1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc);
01232 ossl_i2d_ASN1_TYPE(asn1, &p);
01233 } else {
01234 ossl_i2d_ASN1_TYPE(asn1, &p);
01235 *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
01236 }
01237 ossl_ASN1_TYPE_free(asn1);
01238 reallen = p - buf;
01239 assert(reallen <= len);
01240 str = ossl_buf2str((char *)buf, rb_long2int(reallen));
01241
01242 return str;
01243 }
01244
01245
01246
01247
01248
01249
01250
01251 static VALUE
01252 ossl_asn1cons_to_der(VALUE self)
01253 {
01254 int tag, tn, tc, explicit, constructed = 1;
01255 int found_prim = 0, seq_len;
01256 long length;
01257 unsigned char *p;
01258 VALUE value, str, inf_length;
01259
01260 tn = NUM2INT(ossl_asn1_get_tag(self));
01261 tc = ossl_asn1_tag_class(self);
01262 inf_length = ossl_asn1_get_infinite_length(self);
01263 if (inf_length == Qtrue) {
01264 VALUE ary, example;
01265 constructed = 2;
01266 if (CLASS_OF(self) == cASN1Sequence ||
01267 CLASS_OF(self) == cASN1Set) {
01268 tag = ossl_asn1_default_tag(self);
01269 }
01270 else {
01271 ary = ossl_asn1_get_value(self);
01272 if (!rb_obj_is_kind_of(ary, rb_cArray))
01273 ossl_raise(eASN1Error, "Constructive value must be an Array");
01274
01275
01276
01277
01278 while (!found_prim){
01279 example = rb_ary_entry(ary, 0);
01280 if (rb_obj_is_kind_of(example, cASN1Primitive)){
01281 found_prim = 1;
01282 }
01283 else {
01284
01285 if (!rb_obj_is_kind_of(example, cASN1Constructive)){
01286 ossl_raise(eASN1Error, "invalid constructed encoding");
01287 return Qnil;
01288 }
01289 ary = ossl_asn1_get_value(example);
01290 }
01291 }
01292 tag = ossl_asn1_default_tag(example);
01293 }
01294 }
01295 else {
01296 if (CLASS_OF(self) == cASN1Constructive)
01297 ossl_raise(eASN1Error, "Constructive shall only be used with infinite length");
01298 tag = ossl_asn1_default_tag(self);
01299 }
01300 explicit = ossl_asn1_is_explicit(self);
01301 value = join_der(ossl_asn1_get_value(self));
01302
01303 seq_len = ossl_asn1_object_size(constructed, RSTRING_LENINT(value), tag);
01304 length = ossl_asn1_object_size(constructed, seq_len, tn);
01305 str = rb_str_new(0, length);
01306 p = (unsigned char *)RSTRING_PTR(str);
01307 if(tc == V_ASN1_UNIVERSAL)
01308 ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
01309 else{
01310 if(explicit){
01311 ossl_asn1_put_object(&p, constructed, seq_len, tn, tc);
01312 ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tag, V_ASN1_UNIVERSAL);
01313 }
01314 else{
01315 ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
01316 }
01317 }
01318 memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
01319 p += RSTRING_LEN(value);
01320
01321
01322
01323
01324
01325
01326 if (explicit && inf_length == Qtrue) {
01327 ASN1_put_eoc(&p);
01328 }
01329 ossl_str_adjust(str, p);
01330
01331 return str;
01332 }
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347 static VALUE
01348 ossl_asn1cons_each(VALUE self)
01349 {
01350 rb_ary_each(ossl_asn1_get_value(self));
01351 return self;
01352 }
01353
01354 static VALUE
01355 ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
01356 {
01357 StringValue(oid);
01358 StringValue(sn);
01359 StringValue(ln);
01360
01361 if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln)))
01362 ossl_raise(eASN1Error, NULL);
01363
01364 return Qtrue;
01365 }
01366
01367 static VALUE
01368 ossl_asn1obj_get_sn(VALUE self)
01369 {
01370 VALUE val, ret = Qnil;
01371 int nid;
01372
01373 val = ossl_asn1_get_value(self);
01374 if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef)
01375 ret = rb_str_new2(OBJ_nid2sn(nid));
01376
01377 return ret;
01378 }
01379
01380 static VALUE
01381 ossl_asn1obj_get_ln(VALUE self)
01382 {
01383 VALUE val, ret = Qnil;
01384 int nid;
01385
01386 val = ossl_asn1_get_value(self);
01387 if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef)
01388 ret = rb_str_new2(OBJ_nid2ln(nid));
01389
01390 return ret;
01391 }
01392
01393 static VALUE
01394 ossl_asn1obj_get_oid(VALUE self)
01395 {
01396 VALUE val;
01397 ASN1_OBJECT *a1obj;
01398 char buf[128];
01399
01400 val = ossl_asn1_get_value(self);
01401 a1obj = obj_to_asn1obj(val);
01402 OBJ_obj2txt(buf, sizeof(buf), a1obj, 1);
01403 ASN1_OBJECT_free(a1obj);
01404
01405 return rb_str_new2(buf);
01406 }
01407
01408 #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
01409 static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
01410 { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); }
01411
01412 OSSL_ASN1_IMPL_FACTORY_METHOD(Boolean)
01413 OSSL_ASN1_IMPL_FACTORY_METHOD(Integer)
01414 OSSL_ASN1_IMPL_FACTORY_METHOD(Enumerated)
01415 OSSL_ASN1_IMPL_FACTORY_METHOD(BitString)
01416 OSSL_ASN1_IMPL_FACTORY_METHOD(OctetString)
01417 OSSL_ASN1_IMPL_FACTORY_METHOD(UTF8String)
01418 OSSL_ASN1_IMPL_FACTORY_METHOD(NumericString)
01419 OSSL_ASN1_IMPL_FACTORY_METHOD(PrintableString)
01420 OSSL_ASN1_IMPL_FACTORY_METHOD(T61String)
01421 OSSL_ASN1_IMPL_FACTORY_METHOD(VideotexString)
01422 OSSL_ASN1_IMPL_FACTORY_METHOD(IA5String)
01423 OSSL_ASN1_IMPL_FACTORY_METHOD(GraphicString)
01424 OSSL_ASN1_IMPL_FACTORY_METHOD(ISO64String)
01425 OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralString)
01426 OSSL_ASN1_IMPL_FACTORY_METHOD(UniversalString)
01427 OSSL_ASN1_IMPL_FACTORY_METHOD(BMPString)
01428 OSSL_ASN1_IMPL_FACTORY_METHOD(Null)
01429 OSSL_ASN1_IMPL_FACTORY_METHOD(ObjectId)
01430 OSSL_ASN1_IMPL_FACTORY_METHOD(UTCTime)
01431 OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralizedTime)
01432 OSSL_ASN1_IMPL_FACTORY_METHOD(Sequence)
01433 OSSL_ASN1_IMPL_FACTORY_METHOD(Set)
01434 OSSL_ASN1_IMPL_FACTORY_METHOD(EndOfContent)
01435
01436 void
01437 Init_ossl_asn1()
01438 {
01439 VALUE ary;
01440 int i;
01441
01442 #if 0
01443 mOSSL = rb_define_module("OpenSSL");
01444 #endif
01445
01446 sUNIVERSAL = rb_intern("UNIVERSAL");
01447 sCONTEXT_SPECIFIC = rb_intern("CONTEXT_SPECIFIC");
01448 sAPPLICATION = rb_intern("APPLICATION");
01449 sPRIVATE = rb_intern("PRIVATE");
01450 sEXPLICIT = rb_intern("EXPLICIT");
01451 sIMPLICIT = rb_intern("IMPLICIT");
01452
01453 sivVALUE = rb_intern("@value");
01454 sivTAG = rb_intern("@tag");
01455 sivTAGGING = rb_intern("@tagging");
01456 sivTAG_CLASS = rb_intern("@tag_class");
01457 sivINFINITE_LENGTH = rb_intern("@infinite_length");
01458 sivUNUSED_BITS = rb_intern("@unused_bits");
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586 mASN1 = rb_define_module_under(mOSSL, "ASN1");
01587
01588
01589
01590
01591
01592
01593 eASN1Error = rb_define_class_under(mASN1, "ASN1Error", eOSSLError);
01594 rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
01595 rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
01596 rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);
01597 ary = rb_ary_new();
01598
01599
01600
01601
01602 rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary);
01603 for(i = 0; i < ossl_asn1_info_size; i++){
01604 if(ossl_asn1_info[i].name[0] == '[') continue;
01605 rb_define_const(mASN1, ossl_asn1_info[i].name, INT2NUM(i));
01606 rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name));
01607 }
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696 cASN1Data = rb_define_class_under(mASN1, "ASN1Data", rb_cObject);
01697
01698
01699
01700
01701
01702 rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
01703
01704
01705
01706 rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
01707
01708
01709
01710
01711 rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729 rb_attr(cASN1Data, rb_intern("infinite_length"), 1, 1, 0);
01730 rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
01731 rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793 cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data);
01794
01795
01796
01797
01798
01799
01800 rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
01801 rb_undef_method(cASN1Primitive, "infinite_length=");
01802 rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
01803 rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867 cASN1Constructive = rb_define_class_under(mASN1,"Constructive", cASN1Data);
01868 rb_include_module(cASN1Constructive, rb_mEnumerable);
01869
01870
01871
01872
01873
01874
01875 rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue);
01876 rb_define_method(cASN1Constructive, "initialize", ossl_asn1_initialize, -1);
01877 rb_define_method(cASN1Constructive, "to_der", ossl_asn1cons_to_der, 0);
01878 rb_define_method(cASN1Constructive, "each", ossl_asn1cons_each, 0);
01879
01880 #define OSSL_ASN1_DEFINE_CLASS(name, super) \
01881 do{\
01882 cASN1##name = rb_define_class_under(mASN1, #name, cASN1##super);\
01883 rb_define_module_function(mASN1, #name, ossl_asn1_##name, -1);\
01884 }while(0)
01885
01886 OSSL_ASN1_DEFINE_CLASS(Boolean, Primitive);
01887 OSSL_ASN1_DEFINE_CLASS(Integer, Primitive);
01888 OSSL_ASN1_DEFINE_CLASS(Enumerated, Primitive);
01889 OSSL_ASN1_DEFINE_CLASS(BitString, Primitive);
01890 OSSL_ASN1_DEFINE_CLASS(OctetString, Primitive);
01891 OSSL_ASN1_DEFINE_CLASS(UTF8String, Primitive);
01892 OSSL_ASN1_DEFINE_CLASS(NumericString, Primitive);
01893 OSSL_ASN1_DEFINE_CLASS(PrintableString, Primitive);
01894 OSSL_ASN1_DEFINE_CLASS(T61String, Primitive);
01895 OSSL_ASN1_DEFINE_CLASS(VideotexString, Primitive);
01896 OSSL_ASN1_DEFINE_CLASS(IA5String, Primitive);
01897 OSSL_ASN1_DEFINE_CLASS(GraphicString, Primitive);
01898 OSSL_ASN1_DEFINE_CLASS(ISO64String, Primitive);
01899 OSSL_ASN1_DEFINE_CLASS(GeneralString, Primitive);
01900 OSSL_ASN1_DEFINE_CLASS(UniversalString, Primitive);
01901 OSSL_ASN1_DEFINE_CLASS(BMPString, Primitive);
01902 OSSL_ASN1_DEFINE_CLASS(Null, Primitive);
01903 OSSL_ASN1_DEFINE_CLASS(ObjectId, Primitive);
01904 OSSL_ASN1_DEFINE_CLASS(UTCTime, Primitive);
01905 OSSL_ASN1_DEFINE_CLASS(GeneralizedTime, Primitive);
01906
01907 OSSL_ASN1_DEFINE_CLASS(Sequence, Constructive);
01908 OSSL_ASN1_DEFINE_CLASS(Set, Constructive);
01909
01910 OSSL_ASN1_DEFINE_CLASS(EndOfContent, Data);
01911
01912 rb_define_singleton_method(cASN1ObjectId, "register", ossl_asn1obj_s_register, 3);
01913 rb_define_method(cASN1ObjectId, "sn", ossl_asn1obj_get_sn, 0);
01914 rb_define_method(cASN1ObjectId, "ln", ossl_asn1obj_get_ln, 0);
01915 rb_define_method(cASN1ObjectId, "oid", ossl_asn1obj_get_oid, 0);
01916 rb_define_alias(cASN1ObjectId, "short_name", "sn");
01917 rb_define_alias(cASN1ObjectId, "long_name", "ln");
01918 rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
01919
01920 rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
01921
01922 class_tag_map = rb_hash_new();
01923 rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
01924 rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
01925 rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
01926 rb_hash_aset(class_tag_map, cASN1BitString, INT2NUM(V_ASN1_BIT_STRING));
01927 rb_hash_aset(class_tag_map, cASN1OctetString, INT2NUM(V_ASN1_OCTET_STRING));
01928 rb_hash_aset(class_tag_map, cASN1Null, INT2NUM(V_ASN1_NULL));
01929 rb_hash_aset(class_tag_map, cASN1ObjectId, INT2NUM(V_ASN1_OBJECT));
01930 rb_hash_aset(class_tag_map, cASN1Enumerated, INT2NUM(V_ASN1_ENUMERATED));
01931 rb_hash_aset(class_tag_map, cASN1UTF8String, INT2NUM(V_ASN1_UTF8STRING));
01932 rb_hash_aset(class_tag_map, cASN1Sequence, INT2NUM(V_ASN1_SEQUENCE));
01933 rb_hash_aset(class_tag_map, cASN1Set, INT2NUM(V_ASN1_SET));
01934 rb_hash_aset(class_tag_map, cASN1NumericString, INT2NUM(V_ASN1_NUMERICSTRING));
01935 rb_hash_aset(class_tag_map, cASN1PrintableString, INT2NUM(V_ASN1_PRINTABLESTRING));
01936 rb_hash_aset(class_tag_map, cASN1T61String, INT2NUM(V_ASN1_T61STRING));
01937 rb_hash_aset(class_tag_map, cASN1VideotexString, INT2NUM(V_ASN1_VIDEOTEXSTRING));
01938 rb_hash_aset(class_tag_map, cASN1IA5String, INT2NUM(V_ASN1_IA5STRING));
01939 rb_hash_aset(class_tag_map, cASN1UTCTime, INT2NUM(V_ASN1_UTCTIME));
01940 rb_hash_aset(class_tag_map, cASN1GeneralizedTime, INT2NUM(V_ASN1_GENERALIZEDTIME));
01941 rb_hash_aset(class_tag_map, cASN1GraphicString, INT2NUM(V_ASN1_GRAPHICSTRING));
01942 rb_hash_aset(class_tag_map, cASN1ISO64String, INT2NUM(V_ASN1_ISO64STRING));
01943 rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
01944 rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
01945 rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
01946 rb_global_variable(&class_tag_map);
01947 }
01948