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, long 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, long 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, long 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, long 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, long 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, long 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, long 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, long 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_class(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(RB_BLOCK_CALL_FUNC_ARGLIST(i, 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, long 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, hlen;
00941 int 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 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 RB_GC_GUARD(tmp);
01041 int_ossl_decode_sanity_check(len, read, offset);
01042 return Qnil;
01043 }
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 static VALUE
01058 ossl_asn1_decode(VALUE self, VALUE obj)
01059 {
01060 VALUE ret;
01061 unsigned char *p;
01062 VALUE tmp;
01063 long len, read = 0, offset = 0;
01064
01065 obj = ossl_to_der_if_possible(obj);
01066 tmp = rb_str_new4(StringValue(obj));
01067 p = (unsigned char *)RSTRING_PTR(tmp);
01068 len = RSTRING_LEN(tmp);
01069 ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read);
01070 RB_GC_GUARD(tmp);
01071 int_ossl_decode_sanity_check(len, read, offset);
01072 return ret;
01073 }
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 static VALUE
01089 ossl_asn1_decode_all(VALUE self, VALUE obj)
01090 {
01091 VALUE ary, val;
01092 unsigned char *p;
01093 long len, tmp_len = 0, read = 0, offset = 0;
01094 VALUE tmp;
01095
01096 obj = ossl_to_der_if_possible(obj);
01097 tmp = rb_str_new4(StringValue(obj));
01098 p = (unsigned char *)RSTRING_PTR(tmp);
01099 len = RSTRING_LEN(tmp);
01100 tmp_len = len;
01101 ary = rb_ary_new();
01102 while (tmp_len > 0) {
01103 long tmp_read = 0;
01104 val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read);
01105 rb_ary_push(ary, val);
01106 read += tmp_read;
01107 tmp_len -= tmp_read;
01108 }
01109 RB_GC_GUARD(tmp);
01110 int_ossl_decode_sanity_check(len, read, offset);
01111 return ary;
01112 }
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137 static VALUE
01138 ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
01139 {
01140 VALUE value, tag, tagging, tag_class;
01141
01142 rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
01143 if(argc > 1){
01144 if(NIL_P(tag))
01145 ossl_raise(eASN1Error, "must specify tag number");
01146 if(!NIL_P(tagging) && !SYMBOL_P(tagging))
01147 ossl_raise(eASN1Error, "invalid tagging method");
01148 if(NIL_P(tag_class)) {
01149 if (NIL_P(tagging))
01150 tag_class = ID2SYM(sUNIVERSAL);
01151 else
01152 tag_class = ID2SYM(sCONTEXT_SPECIFIC);
01153 }
01154 if(!SYMBOL_P(tag_class))
01155 ossl_raise(eASN1Error, "invalid tag class");
01156 if(!NIL_P(tagging) && SYM2ID(tagging) == sIMPLICIT && NUM2INT(tag) > 31)
01157 ossl_raise(eASN1Error, "tag number for Universal too large");
01158 }
01159 else{
01160 tag = INT2NUM(ossl_asn1_default_tag(self));
01161 tagging = Qnil;
01162 tag_class = ID2SYM(sUNIVERSAL);
01163 }
01164 ossl_asn1_set_tag(self, tag);
01165 ossl_asn1_set_value(self, value);
01166 ossl_asn1_set_tagging(self, tagging);
01167 ossl_asn1_set_tag_class(self, tag_class);
01168 ossl_asn1_set_infinite_length(self, Qfalse);
01169
01170 return self;
01171 }
01172
01173 static VALUE
01174 ossl_asn1eoc_initialize(VALUE self) {
01175 VALUE tag, tagging, tag_class, value;
01176 tag = INT2NUM(ossl_asn1_default_tag(self));
01177 tagging = Qnil;
01178 tag_class = ID2SYM(sUNIVERSAL);
01179 value = rb_str_new("", 0);
01180 ossl_asn1_set_tag(self, tag);
01181 ossl_asn1_set_value(self, value);
01182 ossl_asn1_set_tagging(self, tagging);
01183 ossl_asn1_set_tag_class(self, tag_class);
01184 ossl_asn1_set_infinite_length(self, Qfalse);
01185 return self;
01186 }
01187
01188 static int
01189 ossl_i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp)
01190 {
01191 #if OPENSSL_VERSION_NUMBER < 0x00907000L
01192 if(!a) return 0;
01193 if(a->type == V_ASN1_BOOLEAN)
01194 return i2d_ASN1_BOOLEAN(a->value.boolean, pp);
01195 #endif
01196 return i2d_ASN1_TYPE(a, pp);
01197 }
01198
01199 static void
01200 ossl_ASN1_TYPE_free(ASN1_TYPE *a)
01201 {
01202 #if OPENSSL_VERSION_NUMBER < 0x00907000L
01203 if(!a) return;
01204 if(a->type == V_ASN1_BOOLEAN){
01205 OPENSSL_free(a);
01206 return;
01207 }
01208 #endif
01209 ASN1_TYPE_free(a);
01210 }
01211
01212
01213
01214
01215
01216
01217
01218 static VALUE
01219 ossl_asn1prim_to_der(VALUE self)
01220 {
01221 ASN1_TYPE *asn1;
01222 int tn, tc, explicit;
01223 long len, reallen;
01224 unsigned char *buf, *p;
01225 VALUE str;
01226
01227 tn = NUM2INT(ossl_asn1_get_tag(self));
01228 tc = ossl_asn1_tag_class(self);
01229 explicit = ossl_asn1_is_explicit(self);
01230 asn1 = ossl_asn1_get_asn1type(self);
01231
01232 len = ossl_asn1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn);
01233 if(!(buf = OPENSSL_malloc(len))){
01234 ossl_ASN1_TYPE_free(asn1);
01235 ossl_raise(eASN1Error, "cannot alloc buffer");
01236 }
01237 p = buf;
01238 if (tc == V_ASN1_UNIVERSAL) {
01239 ossl_i2d_ASN1_TYPE(asn1, &p);
01240 } else if (explicit) {
01241 ossl_asn1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc);
01242 ossl_i2d_ASN1_TYPE(asn1, &p);
01243 } else {
01244 ossl_i2d_ASN1_TYPE(asn1, &p);
01245 *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
01246 }
01247 ossl_ASN1_TYPE_free(asn1);
01248 reallen = p - buf;
01249 assert(reallen <= len);
01250 str = ossl_buf2str((char *)buf, rb_long2int(reallen));
01251
01252 return str;
01253 }
01254
01255
01256
01257
01258
01259
01260
01261 static VALUE
01262 ossl_asn1cons_to_der(VALUE self)
01263 {
01264 int tag, tn, tc, explicit, constructed = 1;
01265 int found_prim = 0, seq_len;
01266 long length;
01267 unsigned char *p;
01268 VALUE value, str, inf_length;
01269
01270 tn = NUM2INT(ossl_asn1_get_tag(self));
01271 tc = ossl_asn1_tag_class(self);
01272 inf_length = ossl_asn1_get_infinite_length(self);
01273 if (inf_length == Qtrue) {
01274 VALUE ary, example;
01275 constructed = 2;
01276 if (CLASS_OF(self) == cASN1Sequence ||
01277 CLASS_OF(self) == cASN1Set) {
01278 tag = ossl_asn1_default_tag(self);
01279 }
01280 else {
01281 ary = ossl_asn1_get_value(self);
01282 if (!rb_obj_is_kind_of(ary, rb_cArray))
01283 ossl_raise(eASN1Error, "Constructive value must be an Array");
01284
01285
01286
01287
01288 while (!found_prim){
01289 example = rb_ary_entry(ary, 0);
01290 if (rb_obj_is_kind_of(example, cASN1Primitive)){
01291 found_prim = 1;
01292 }
01293 else {
01294
01295 if (!rb_obj_is_kind_of(example, cASN1Constructive)){
01296 ossl_raise(eASN1Error, "invalid constructed encoding");
01297 return Qnil;
01298 }
01299 ary = ossl_asn1_get_value(example);
01300 }
01301 }
01302 tag = ossl_asn1_default_tag(example);
01303 }
01304 }
01305 else {
01306 if (CLASS_OF(self) == cASN1Constructive)
01307 ossl_raise(eASN1Error, "Constructive shall only be used with infinite length");
01308 tag = ossl_asn1_default_tag(self);
01309 }
01310 explicit = ossl_asn1_is_explicit(self);
01311 value = join_der(ossl_asn1_get_value(self));
01312
01313 seq_len = ossl_asn1_object_size(constructed, RSTRING_LENINT(value), tag);
01314 length = ossl_asn1_object_size(constructed, seq_len, tn);
01315 str = rb_str_new(0, length);
01316 p = (unsigned char *)RSTRING_PTR(str);
01317 if(tc == V_ASN1_UNIVERSAL)
01318 ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
01319 else{
01320 if(explicit){
01321 ossl_asn1_put_object(&p, constructed, seq_len, tn, tc);
01322 ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tag, V_ASN1_UNIVERSAL);
01323 }
01324 else{
01325 ossl_asn1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
01326 }
01327 }
01328 memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
01329 p += RSTRING_LEN(value);
01330
01331
01332
01333
01334
01335
01336 if (explicit && inf_length == Qtrue) {
01337 ASN1_put_eoc(&p);
01338 }
01339 ossl_str_adjust(str, p);
01340
01341 return str;
01342 }
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357 static VALUE
01358 ossl_asn1cons_each(VALUE self)
01359 {
01360 rb_ary_each(ossl_asn1_get_value(self));
01361 return self;
01362 }
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375 static VALUE
01376 ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
01377 {
01378 StringValue(oid);
01379 StringValue(sn);
01380 StringValue(ln);
01381
01382 if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln)))
01383 ossl_raise(eASN1Error, NULL);
01384
01385 return Qtrue;
01386 }
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 static VALUE
01397 ossl_asn1obj_get_sn(VALUE self)
01398 {
01399 VALUE val, ret = Qnil;
01400 int nid;
01401
01402 val = ossl_asn1_get_value(self);
01403 if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef)
01404 ret = rb_str_new2(OBJ_nid2sn(nid));
01405
01406 return ret;
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417 static VALUE
01418 ossl_asn1obj_get_ln(VALUE self)
01419 {
01420 VALUE val, ret = Qnil;
01421 int nid;
01422
01423 val = ossl_asn1_get_value(self);
01424 if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef)
01425 ret = rb_str_new2(OBJ_nid2ln(nid));
01426
01427 return ret;
01428 }
01429
01430
01431
01432
01433
01434 static VALUE
01435 ossl_asn1obj_get_oid(VALUE self)
01436 {
01437 VALUE val;
01438 ASN1_OBJECT *a1obj;
01439 char buf[128];
01440
01441 val = ossl_asn1_get_value(self);
01442 a1obj = obj_to_asn1obj(val);
01443 OBJ_obj2txt(buf, sizeof(buf), a1obj, 1);
01444 ASN1_OBJECT_free(a1obj);
01445
01446 return rb_str_new2(buf);
01447 }
01448
01449 #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
01450 static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
01451 { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); }
01452
01453 OSSL_ASN1_IMPL_FACTORY_METHOD(Boolean)
01454 OSSL_ASN1_IMPL_FACTORY_METHOD(Integer)
01455 OSSL_ASN1_IMPL_FACTORY_METHOD(Enumerated)
01456 OSSL_ASN1_IMPL_FACTORY_METHOD(BitString)
01457 OSSL_ASN1_IMPL_FACTORY_METHOD(OctetString)
01458 OSSL_ASN1_IMPL_FACTORY_METHOD(UTF8String)
01459 OSSL_ASN1_IMPL_FACTORY_METHOD(NumericString)
01460 OSSL_ASN1_IMPL_FACTORY_METHOD(PrintableString)
01461 OSSL_ASN1_IMPL_FACTORY_METHOD(T61String)
01462 OSSL_ASN1_IMPL_FACTORY_METHOD(VideotexString)
01463 OSSL_ASN1_IMPL_FACTORY_METHOD(IA5String)
01464 OSSL_ASN1_IMPL_FACTORY_METHOD(GraphicString)
01465 OSSL_ASN1_IMPL_FACTORY_METHOD(ISO64String)
01466 OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralString)
01467 OSSL_ASN1_IMPL_FACTORY_METHOD(UniversalString)
01468 OSSL_ASN1_IMPL_FACTORY_METHOD(BMPString)
01469 OSSL_ASN1_IMPL_FACTORY_METHOD(Null)
01470 OSSL_ASN1_IMPL_FACTORY_METHOD(ObjectId)
01471 OSSL_ASN1_IMPL_FACTORY_METHOD(UTCTime)
01472 OSSL_ASN1_IMPL_FACTORY_METHOD(GeneralizedTime)
01473 OSSL_ASN1_IMPL_FACTORY_METHOD(Sequence)
01474 OSSL_ASN1_IMPL_FACTORY_METHOD(Set)
01475 OSSL_ASN1_IMPL_FACTORY_METHOD(EndOfContent)
01476
01477 void
01478 Init_ossl_asn1()
01479 {
01480 VALUE ary;
01481 int i;
01482
01483 #if 0
01484 mOSSL = rb_define_module("OpenSSL");
01485 #endif
01486
01487 sUNIVERSAL = rb_intern("UNIVERSAL");
01488 sCONTEXT_SPECIFIC = rb_intern("CONTEXT_SPECIFIC");
01489 sAPPLICATION = rb_intern("APPLICATION");
01490 sPRIVATE = rb_intern("PRIVATE");
01491 sEXPLICIT = rb_intern("EXPLICIT");
01492 sIMPLICIT = rb_intern("IMPLICIT");
01493
01494 sivVALUE = rb_intern("@value");
01495 sivTAG = rb_intern("@tag");
01496 sivTAGGING = rb_intern("@tagging");
01497 sivTAG_CLASS = rb_intern("@tag_class");
01498 sivINFINITE_LENGTH = rb_intern("@infinite_length");
01499 sivUNUSED_BITS = rb_intern("@unused_bits");
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
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627 mASN1 = rb_define_module_under(mOSSL, "ASN1");
01628
01629
01630
01631
01632
01633
01634 eASN1Error = rb_define_class_under(mASN1, "ASN1Error", eOSSLError);
01635 rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
01636 rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
01637 rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);
01638 ary = rb_ary_new();
01639
01640
01641
01642
01643 rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary);
01644 for(i = 0; i < ossl_asn1_info_size; i++){
01645 if(ossl_asn1_info[i].name[0] == '[') continue;
01646 rb_define_const(mASN1, ossl_asn1_info[i].name, INT2NUM(i));
01647 rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name));
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
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737 cASN1Data = rb_define_class_under(mASN1, "ASN1Data", rb_cObject);
01738
01739
01740
01741
01742
01743 rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
01744
01745
01746
01747 rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
01748
01749
01750
01751
01752 rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770 rb_attr(cASN1Data, rb_intern("infinite_length"), 1, 1, 0);
01771 rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
01772 rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
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
01801
01802
01803
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 cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data);
01839
01840
01841
01842
01843
01844
01845 rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
01846 rb_undef_method(cASN1Primitive, "infinite_length=");
01847 rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
01848 rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
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
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912 cASN1Constructive = rb_define_class_under(mASN1,"Constructive", cASN1Data);
01913 rb_include_module(cASN1Constructive, rb_mEnumerable);
01914
01915
01916
01917
01918
01919
01920 rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue);
01921 rb_define_method(cASN1Constructive, "initialize", ossl_asn1_initialize, -1);
01922 rb_define_method(cASN1Constructive, "to_der", ossl_asn1cons_to_der, 0);
01923 rb_define_method(cASN1Constructive, "each", ossl_asn1cons_each, 0);
01924
01925 #define OSSL_ASN1_DEFINE_CLASS(name, super) \
01926 do{\
01927 cASN1##name = rb_define_class_under(mASN1, #name, cASN1##super);\
01928 rb_define_module_function(mASN1, #name, ossl_asn1_##name, -1);\
01929 }while(0)
01930
01931 OSSL_ASN1_DEFINE_CLASS(Boolean, Primitive);
01932 OSSL_ASN1_DEFINE_CLASS(Integer, Primitive);
01933 OSSL_ASN1_DEFINE_CLASS(Enumerated, Primitive);
01934 OSSL_ASN1_DEFINE_CLASS(BitString, Primitive);
01935 OSSL_ASN1_DEFINE_CLASS(OctetString, Primitive);
01936 OSSL_ASN1_DEFINE_CLASS(UTF8String, Primitive);
01937 OSSL_ASN1_DEFINE_CLASS(NumericString, Primitive);
01938 OSSL_ASN1_DEFINE_CLASS(PrintableString, Primitive);
01939 OSSL_ASN1_DEFINE_CLASS(T61String, Primitive);
01940 OSSL_ASN1_DEFINE_CLASS(VideotexString, Primitive);
01941 OSSL_ASN1_DEFINE_CLASS(IA5String, Primitive);
01942 OSSL_ASN1_DEFINE_CLASS(GraphicString, Primitive);
01943 OSSL_ASN1_DEFINE_CLASS(ISO64String, Primitive);
01944 OSSL_ASN1_DEFINE_CLASS(GeneralString, Primitive);
01945 OSSL_ASN1_DEFINE_CLASS(UniversalString, Primitive);
01946 OSSL_ASN1_DEFINE_CLASS(BMPString, Primitive);
01947 OSSL_ASN1_DEFINE_CLASS(Null, Primitive);
01948 OSSL_ASN1_DEFINE_CLASS(ObjectId, Primitive);
01949 OSSL_ASN1_DEFINE_CLASS(UTCTime, Primitive);
01950 OSSL_ASN1_DEFINE_CLASS(GeneralizedTime, Primitive);
01951
01952 OSSL_ASN1_DEFINE_CLASS(Sequence, Constructive);
01953 OSSL_ASN1_DEFINE_CLASS(Set, Constructive);
01954
01955 OSSL_ASN1_DEFINE_CLASS(EndOfContent, Data);
01956
01957
01958
01959
01960
01961
01962 #if 0
01963 cASN1ObjectId = rb_define_class_under(mASN1, "ObjectId", cASN1Primitive);
01964 #endif
01965 rb_define_singleton_method(cASN1ObjectId, "register", ossl_asn1obj_s_register, 3);
01966 rb_define_method(cASN1ObjectId, "sn", ossl_asn1obj_get_sn, 0);
01967 rb_define_method(cASN1ObjectId, "ln", ossl_asn1obj_get_ln, 0);
01968 rb_define_method(cASN1ObjectId, "oid", ossl_asn1obj_get_oid, 0);
01969 rb_define_alias(cASN1ObjectId, "short_name", "sn");
01970 rb_define_alias(cASN1ObjectId, "long_name", "ln");
01971 rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
01972
01973 rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
01974
01975 class_tag_map = rb_hash_new();
01976 rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
01977 rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
01978 rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
01979 rb_hash_aset(class_tag_map, cASN1BitString, INT2NUM(V_ASN1_BIT_STRING));
01980 rb_hash_aset(class_tag_map, cASN1OctetString, INT2NUM(V_ASN1_OCTET_STRING));
01981 rb_hash_aset(class_tag_map, cASN1Null, INT2NUM(V_ASN1_NULL));
01982 rb_hash_aset(class_tag_map, cASN1ObjectId, INT2NUM(V_ASN1_OBJECT));
01983 rb_hash_aset(class_tag_map, cASN1Enumerated, INT2NUM(V_ASN1_ENUMERATED));
01984 rb_hash_aset(class_tag_map, cASN1UTF8String, INT2NUM(V_ASN1_UTF8STRING));
01985 rb_hash_aset(class_tag_map, cASN1Sequence, INT2NUM(V_ASN1_SEQUENCE));
01986 rb_hash_aset(class_tag_map, cASN1Set, INT2NUM(V_ASN1_SET));
01987 rb_hash_aset(class_tag_map, cASN1NumericString, INT2NUM(V_ASN1_NUMERICSTRING));
01988 rb_hash_aset(class_tag_map, cASN1PrintableString, INT2NUM(V_ASN1_PRINTABLESTRING));
01989 rb_hash_aset(class_tag_map, cASN1T61String, INT2NUM(V_ASN1_T61STRING));
01990 rb_hash_aset(class_tag_map, cASN1VideotexString, INT2NUM(V_ASN1_VIDEOTEXSTRING));
01991 rb_hash_aset(class_tag_map, cASN1IA5String, INT2NUM(V_ASN1_IA5STRING));
01992 rb_hash_aset(class_tag_map, cASN1UTCTime, INT2NUM(V_ASN1_UTCTIME));
01993 rb_hash_aset(class_tag_map, cASN1GeneralizedTime, INT2NUM(V_ASN1_GENERALIZEDTIME));
01994 rb_hash_aset(class_tag_map, cASN1GraphicString, INT2NUM(V_ASN1_GRAPHICSTRING));
01995 rb_hash_aset(class_tag_map, cASN1ISO64String, INT2NUM(V_ASN1_ISO64STRING));
01996 rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
01997 rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
01998 rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
01999 rb_global_variable(&class_tag_map);
02000 }
02001