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