Class: Krypt::ASN1::Header
- Inherits:
-
Object
- Object
- Krypt::ASN1::Header
- Defined in:
- ext/krypt/core/krypt_asn1_parser.c,
ext/krypt/core/krypt_asn1_parser.c
Overview
These are the tokens returned by Parser#next and cannot be instantiated on their own. A Header represents the Tag and Length part of a TLV (Tag-Length-Value) DER encoding, and it also allows to move the “cursor” on an IO forward by consuming or skipping the associated value (the V).
The Header itself contains tag and length information of what was just parsed:
-
tag number (Header#tag)
-
tag class (Header#tag_class)
-
whether the header is constructed or not (Header#constructed?)
-
whether it is an infinite length value or not (Header#infinite?)
-
the length in bytes of the associated value (Header#length/size)
-
the length of the raw Header encoding (Header#header_length/header_size)
In addition, there are three ways to consume the value that is associated with a Header:
-
by skipping it (Header#skip_value)
-
by reading the value in one single pass (Header#value)
-
or by obtaining an Instream of the value bytes so that it can be consumed in a streaming fashion (Header#value_io)
Access to the raw encoding of the Header is given by either retrieving a String containing the encoding with Header#bytes or by encoding it to an IO-like object supporting IO#write using Header#encode_to.
Instance Method Summary collapse
-
#bytes ⇒ String
Returns a
String
containing the raw byte encoding of this Header. -
#constructed? ⇒ Boolean
call-seq: header.constructed? -> true or false.
- #encode_to ⇒ Object
-
#header_length ⇒ Object
(also: #header_size)
call-seq: header.header_length -> Number.
-
#infinite? ⇒ Boolean
call-seq: header.infinite? -> true or false.
-
#length ⇒ Object
(also: #size)
call-seq: header.length -> Number.
-
#skip_value ⇒ nil
Simply moves the “cursor” on the underlying IO forward by skipping over the bytes that represent the value associated with this Header.
-
#tag ⇒ Object
call-seq: header.tag -> Number.
-
#tag_class ⇒ Object
call-seq: header.tag_class -> Symbol.
-
#to_s ⇒ String
Prints out the information about this Header in a human-readable format without consuming (and therefore also not displaying) the associated value.
-
#value ⇒ String?
Returns the raw byte encoding of the associated value.
-
#value_io ⇒ Instream
Returns a Krypt::ASN1::Instream that allows consuming the value in streaming manner rather than buffering it in a
String
and consuming it at once.
Instance Method Details
#bytes ⇒ String
Returns a String
containing the raw byte encoding of this Header.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'ext/krypt/core/krypt_asn1_parser.c', line 229
static VALUE
krypt_asn1_header_bytes(VALUE self)
{
krypt_asn1_parsed_header *header;
uint8_t *bytes;
size_t size;
binyo_outstream *out;
VALUE ret;
int_asn1_parsed_header_get(self, header);
out = binyo_outstream_new_bytes();
if (krypt_asn1_header_encode(out, header->header) == KRYPT_ERR) {
binyo_outstream_free(out);
krypt_error_raise(eKryptASN1SerializeError, "Error while encoding ASN.1 header");
}
size = binyo_outstream_bytes_get_bytes_free(out, &bytes);
ret = rb_str_new((const char *)bytes, size);
rb_enc_associate(ret, rb_ascii8bit_encoding());
xfree(bytes);
return ret;
}
|
#constructed? ⇒ Boolean
call-seq:
header.constructed? -> true or false
true
if the current Header belongs to a constructed value, false
otherwise.
#encode_to ⇒ Object
#header_length ⇒ Object Also known as: header_size
call-seq:
header.header_length -> Number
Returns the byte size of the raw header encoding. Never nil
.
#infinite? ⇒ Boolean
call-seq:
header.infinite? -> true or false
true
if the current Header is encoded using infinite length, false
otherwise. Note that an infinite length-encoded value is automatically constructed, i.e. header.constructed? => header.infinite?
#length ⇒ Object Also known as: size
call-seq:
header.length -> Number
Returns a Number
representing the raw byte length of the associated value. It is 0
is the Header represents an infinite length-encoded value. Never nil
.
#skip_value ⇒ nil
Simply moves the “cursor” on the underlying IO forward by skipping over the bytes that represent the value associated with this Header. After having called skip_value
, the next Header can be parsed from the underlying IO with Parser#next.
261 262 263 264 265 266 267 268 269 270 |
# File 'ext/krypt/core/krypt_asn1_parser.c', line 261
static VALUE
krypt_asn1_header_skip_value(VALUE self)
{
krypt_asn1_parsed_header *header;
int_asn1_parsed_header_get(self, header);
if (krypt_asn1_skip_value(header->in, header->header) == KRYPT_ERR)
krypt_error_raise(eKryptASN1ParseError, "Skipping the value failed");
return Qnil;
}
|
#tag ⇒ Object
call-seq:
header.tag -> Number
A Number
representing the tag of this Header. Never nil
.
#tag_class ⇒ Object
call-seq:
header.tag_class -> Symbol
A Symbol
representing the tag class of this Header. Never nil
. See Krypt::ASN1::ASN1Data for possible values.
#to_s ⇒ String
Prints out the information about this Header in a human-readable format without consuming (and therefore also not displaying) the associated value.
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'ext/krypt/core/krypt_asn1_parser.c', line 376
static VALUE
krypt_asn1_header_to_s(VALUE self)
{
VALUE str;
krypt_asn1_parsed_header *header;
ID to_s;
int_asn1_parsed_header_get(self, header);
to_s = rb_intern("to_s");
str = rb_str_new2("Tag: ");
rb_str_append(str, rb_funcall(header->tag, to_s, 0));
rb_str_append(str, rb_str_new2(" Tag Class: "));
rb_str_append(str, rb_funcall(header->tag_class, to_s, 0));
rb_str_append(str, rb_str_new2(" Length: "));
rb_str_append(str, rb_funcall(header->length, to_s, 0));
rb_str_append(str, rb_str_new2(" Header Length: "));
rb_str_append(str, rb_funcall(header->header_length, to_s, 0));
rb_str_append(str, rb_str_new2(" Constructed: "));
rb_str_append(str, rb_funcall(header->constructed, to_s, 0));
rb_str_append(str, rb_str_new2(" Infinite Length: "));
rb_str_append(str, rb_funcall(header->infinite, to_s, 0));
return str;
}
|
#value ⇒ String?
Returns the raw byte encoding of the associated value. Also moves the “cursor” on the underlying IO forward. After having called value, the next Header can be parsed from the underlying IO with Parser#next. Once read, the value will be cached and subsequent calls to #value will have no effect on the underlying stream.
If there is no value (indicated * by Header#length == 0), it returns nil
.
May raise Krypt::ASN1::ParseError if an Instream was already obtained by Header#value_io, because the underlying stream can only be consumed once.
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'ext/krypt/core/krypt_asn1_parser.c', line 288
static VALUE
krypt_asn1_header_value(VALUE self)
{
krypt_asn1_parsed_header *header;
int_asn1_parsed_header_get(self, header);
if (header->consumed && header->cached_stream != Qnil)
rb_raise(eKryptASN1ParseError, "The stream has already been consumed");
/* TODO: sync */
if (!header->consumed && header->value == Qnil) {
uint8_t *value;
size_t length;
int tag;
if (krypt_asn1_get_value(header->in, header->header, &value, &length) == KRYPT_ERR)
rb_raise(eKryptASN1ParseError, "Parsing the value failed");
tag = header->header->tag;
if (length != 0 || (tag != TAGS_NULL && tag != TAGS_END_OF_CONTENTS)) {
header->value = rb_str_new((const char *)value, length);
rb_enc_associate(header->value, rb_ascii8bit_encoding());
}
header->consumed = 1;
xfree(value);
}
return header->value;
}
|
#value_io ⇒ Instream
Returns a Krypt::ASN1::Instream that allows consuming the value in streaming manner rather than buffering it in a String
and consuming it at once. Note that once an Instream was obtained in this way, all calls to Header#value will raise a ParseError. Subsequent calls to value_io
are possible, however, the Instream instance is cached.
May raise Krypt::ASN1::ParseError if the associated value was already consumed by a call to Header#value.
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'ext/krypt/core/krypt_asn1_parser.c', line 342
static VALUE
krypt_asn1_header_value_io(int argc, VALUE *argv, VALUE self)
{
krypt_asn1_parsed_header *header;
VALUE values_only;
rb_scan_args(argc, argv, "01", &values_only);
int_asn1_parsed_header_get(self, header);
if (header->consumed && header->cached_stream == Qnil)
rb_raise(eKryptASN1ParseError, "The stream has already been consumed");
/*TODO: synchronization */
if (header->cached_stream == Qnil) {
if (NIL_P(values_only))
values_only = Qtrue;
header->consumed = 1;
header->cached_stream = int_header_cache_stream(header->in,
header->header,
values_only == Qtrue);
}
return header->cached_stream;
}
|