mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Mon May 16 05:13:20 2011 Martin Bosslet <Martin.Bosslet@googlemail.com>
* ext/openssl/ossl_asn1.c: Add documentation. Previous revision: 31583 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31584 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9b710b827d
commit
a5eee54bbe
2 changed files with 500 additions and 1 deletions
|
@ -1,3 +1,7 @@
|
|||
Mon May 16 05:13:20 2011 Martin Bosslet <Martin.Bosslet@googlemail.com>
|
||||
|
||||
* ext/openssl/ossl_asn1.c: Add documentation.
|
||||
|
||||
Mon May 16 00:32:05 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||
|
||||
* test/ruby/test_signal.rb (TestSignal#test_signal_process_group):
|
||||
|
|
|
@ -655,6 +655,20 @@ ossl_asn1_class2sym(int tc)
|
|||
return ID2SYM(sUNIVERSAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) => ASN1Data
|
||||
*
|
||||
* +value+: Please have a look at Constructive and Primitive to see how Ruby
|
||||
* types are mapped to ASN.1 types and vice versa.
|
||||
* +tag+: A +Number+ indicating the tag number.
|
||||
* +tag_class: A +Symbol+ indicating the tag class. Please cf. ASN1 for
|
||||
* possible values.
|
||||
*
|
||||
* == Example
|
||||
* asn1_int = OpenSSL::ASN1Data.new(42, 2, :UNIVERSAL) # => Same as OpenSSL::ASN1::Integer.new(42)
|
||||
* tagged_int = OpenSSL::ASN1Data.new(42, 0, :CONTEXT_SPECIFIC) # implicitly 0-tagged INTEGER
|
||||
*/
|
||||
static VALUE
|
||||
ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
|
||||
{
|
||||
|
@ -687,6 +701,15 @@ join_der(VALUE enumerable)
|
|||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* asn1.to_der => DER-encoded String
|
||||
*
|
||||
* Encodes this ASN1Data into a DER-encoded String value. The result is
|
||||
* DER-encoded except for the possibility of infinite length encodings.
|
||||
* Infinite length encodings are not allowed in strict DER, so strictly
|
||||
* speaking the result of such an encoding would be a BER-encoding.
|
||||
*/
|
||||
static VALUE
|
||||
ossl_asn1data_to_der(VALUE self)
|
||||
{
|
||||
|
@ -855,7 +878,28 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
|
|||
|
||||
return ary;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* OpenSSL::ASN1.traverse(asn1) -> nil
|
||||
*
|
||||
* If a block is given, it prints out each of the elements encountered.
|
||||
* Block parameters are (in that order):
|
||||
* * depth: The recursion depth, plus one with each constructed value being encountered (Number)
|
||||
* * offset: Current byte offset (Number)
|
||||
* * header length: Combined length in bytes of the Tag and Length headers. (Number)
|
||||
* * length: The overall remaining length of the entire data (Number)
|
||||
* * constructed: Whether this value is constructed or not (Boolean)
|
||||
* * tag_class: Current tag class (Symbol)
|
||||
* * tag: The current tag (Number)
|
||||
*
|
||||
* == Example
|
||||
* der = File.binread('asn1data.der')
|
||||
* OpenSSL::ASN1.traverse(der) do | depth, offset, header_len, length, constructed, tag_class, tag|
|
||||
* puts "Depth: #{depth} Offset: #{offset} Length: #{length}"
|
||||
* puts "Header length: #{header_len} Tag: #{tag} Tag class: #{tag_class} Constructed: #{constructed}"
|
||||
* end
|
||||
*/
|
||||
static VALUE
|
||||
ossl_asn1_traverse(VALUE self, VALUE obj)
|
||||
{
|
||||
|
@ -871,6 +915,18 @@ ossl_asn1_traverse(VALUE self, VALUE obj)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* OpenSSL::ASN1.decode(der) -> ASN1Data
|
||||
*
|
||||
* Decodes a BER- or DER-encoded value and creates an ASN1Data instance. +der+
|
||||
* may be a +String+ or any object that features a +#to_der+ method transforming
|
||||
* it into a BER-/DER-encoded +String+.
|
||||
*
|
||||
* == Example
|
||||
* der = File.binread('asn1data')
|
||||
* asn1 = OpenSSL::ASN1.decode(der)
|
||||
*/
|
||||
static VALUE
|
||||
ossl_asn1_decode(VALUE self, VALUE obj)
|
||||
{
|
||||
|
@ -888,6 +944,19 @@ ossl_asn1_decode(VALUE self, VALUE obj)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* OpenSSL::ASN1.decode_all(der) -> Array of ASN1Data
|
||||
*
|
||||
* Similar to +decode+ with the difference that +decode+ expects one
|
||||
* distinct value represented in +der+. +decode_all+ on the contrary
|
||||
* decodes a sequence of sequential BER/DER values lined up in +der+
|
||||
* and returns them as an array.
|
||||
*
|
||||
* == Example
|
||||
* ders = File.binread('asn1data_seq')
|
||||
* asn1_ary = OpenSSL::ASN1.decode_all(ders)
|
||||
*/
|
||||
static VALUE
|
||||
ossl_asn1_decode_all(VALUE self, VALUE obj)
|
||||
{
|
||||
|
@ -904,6 +973,26 @@ ossl_asn1_decode_all(VALUE self, VALUE obj)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* OpenSSL::ASN1::Primitive.new( value [, tag, tagging, tag_class ]) => Primitive
|
||||
*
|
||||
* +value+: is mandatory.
|
||||
* +tag+: optional, may be specified for tagged values. If no +tag+ is
|
||||
* specified, the UNIVERSAL tag corresponding to the Primitive sub-class
|
||||
* is used by default.
|
||||
* +tagging+: may be used as an encoding hint to encode a value either
|
||||
* explicitly or implicitly, see ASN1 for possible values.
|
||||
* +tag_class+: if +tag+ and +tagging+ are +nil+ then this is set to
|
||||
* +:UNIVERSAL+ by default. If either +tag+ or +tagging+ are set then
|
||||
* +:CONTEXT_SPECIFIC+ is used as the default. For possible values please
|
||||
* cf. ASN1.
|
||||
*
|
||||
* == Example
|
||||
* int = OpenSSL::ASN1::Integer.new(42)
|
||||
* zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :IMPLICIT)
|
||||
* private_explicit_zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :EXPLICIT, :PRIVATE)
|
||||
*/
|
||||
static VALUE
|
||||
ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
|
@ -977,6 +1066,12 @@ ossl_ASN1_TYPE_free(ASN1_TYPE *a)
|
|||
ASN1_TYPE_free(a);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* asn1.to_der => DER-encoded String
|
||||
*
|
||||
* See ASN1Data#to_der for details. *
|
||||
*/
|
||||
static VALUE
|
||||
ossl_asn1prim_to_der(VALUE self)
|
||||
{
|
||||
|
@ -1014,6 +1109,12 @@ ossl_asn1prim_to_der(VALUE self)
|
|||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* asn1.to_der => DER-encoded String
|
||||
*
|
||||
* See ASN1Data#to_der for details.
|
||||
*/
|
||||
static VALUE
|
||||
ossl_asn1cons_to_der(VALUE self)
|
||||
{
|
||||
|
@ -1083,6 +1184,19 @@ ossl_asn1cons_to_der(VALUE self)
|
|||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* asn1_ary.each { |asn1| block } => asn1_ary
|
||||
*
|
||||
* Calls <i>block</i> once for each element in +self+, passing that element
|
||||
* as parameter +asn1+. If no block is given, an enumerator is returned
|
||||
* instead.
|
||||
*
|
||||
* == Example
|
||||
* asn1_ary.each do |asn1|
|
||||
* puts asn1
|
||||
* end
|
||||
*/
|
||||
static VALUE
|
||||
ossl_asn1cons_each(VALUE self)
|
||||
{
|
||||
|
@ -1189,12 +1303,148 @@ Init_ossl_asn1()
|
|||
sEXPLICIT = rb_intern("EXPLICIT");
|
||||
sIMPLICIT = rb_intern("IMPLICIT");
|
||||
|
||||
/*
|
||||
* Document-module: OpenSSL::ASN1
|
||||
*
|
||||
* Abstract Syntax Notation One (or ASN.1) is a notation syntax to
|
||||
* describe data structures and is defined in ITU-T X.680. ASN.1 itself
|
||||
* does not mandate any encoding or parsing rules, but usually ASN.1 data
|
||||
* structures are encoded using the Distinguished Encoding Rules (DER) or
|
||||
* less often the Basic Encoding Rules (BER) described in ITU-T X.690. DER
|
||||
* and BER encodings are binary Tag-Length-Value (TLV) encodings that are
|
||||
* quite concise compared to other popular data description formats such
|
||||
* as XML, JSON etc.
|
||||
* ASN.1 data structures are very common in cryptographic applications,
|
||||
* e.g. X.509 public key certificates or certificate revocation lists
|
||||
* (CRLs) are all defined in ASN.1 and DER-encoded. ASN.1, DER and BER are
|
||||
* the building blocks of applied cryptography.
|
||||
* The ASN1 module provides the necessary classes that allow generation
|
||||
* of ASN.1 data structures and the methods to encode them using a DER
|
||||
* encoding. The decode method allows parsing arbitrary BER-/DER-encoded
|
||||
* data to a Ruby object that can then be modified and re-encoded at will.
|
||||
*
|
||||
* == ASN.1 class hierarchy
|
||||
*
|
||||
* The base class representing ASN.1 structues is ASN1Data. ASN1Data offers
|
||||
* attributes to read and set the +tag+, the +tag_class+ and finally the
|
||||
* +value+ of a particular ASN.1 item. Upon parsing, any tagged values
|
||||
* (implicit or explicit) will be represented by ASN1Data instances because
|
||||
* their "real type" can only be determined using out-of-band information
|
||||
* from the ASN.1 type declaration. Since this information is normally
|
||||
* known when encoding a type, all sub-classes of ASN1Data offer an
|
||||
* additional attribute +tagging+ that allows to encode a value implicitly
|
||||
* (+:IMPLICIT+) or explicitly (+:EXPLICIT+).
|
||||
*
|
||||
* === Constructive
|
||||
*
|
||||
* Constructive is, as its name implies, the base class for all
|
||||
* constructed encodings, i.e. those that consist of several values,
|
||||
* opposed to "primitive" encodings with just one single value.
|
||||
* Primitive values that are encoded with "infinite length" are typically
|
||||
* constructed (their values come in multiple chunks) and are therefore
|
||||
* represented by instances of Constructive. The value of an Constructive
|
||||
* is always an Array.
|
||||
*
|
||||
* ==== ASN1::Set and ASN1::Sequence
|
||||
*
|
||||
* The most common constructive encodings are SETs and SEQUENCEs, which is
|
||||
* why there are two sub-classes of Constructive representing each of
|
||||
* them.
|
||||
*
|
||||
* === Primitive
|
||||
*
|
||||
* This is the super class of all primitive values. Primitive
|
||||
* itself is not used when parsing ASN.1 data, all values are either
|
||||
* instances of a corresponding sub-class of Primitive or they are
|
||||
* instances of ASN1Data if the value was tagged implicitly or explicitly.
|
||||
* Please cf. Primitive documentation for details on sub-classes and
|
||||
* their respective mappings of ASN.1 data types to Ruby types.
|
||||
*
|
||||
* == Possible values for attribute +tagging+
|
||||
*
|
||||
* When constructing an ASN1Data object the ASN.1 type definition may
|
||||
* require certain elements to be either implicitly or explicitly tagged.
|
||||
* This can be achieved by setting the +tagging+ attribute manually for
|
||||
* sub-classes of ASN1Data. Use the symbol +:IMPLICIT+ for implicit
|
||||
* tagging and +:EXPLICIT+ if the element requires explicit tagging.
|
||||
*
|
||||
* == Possible values for +tag_class+
|
||||
*
|
||||
* It is possible to create arbitrary ASN1Data objects that also support
|
||||
* a PRIVATE or APPLICATION tag class. Possible values for the +tag_class+
|
||||
* attribute are:
|
||||
* * +:UNIVERSAL+ (the default for untagged values)
|
||||
* * +:CONTEXT_SPECIFIC+ (the default for tagged values)
|
||||
* * +:APPLICATION+
|
||||
* * +:PRIVATE+
|
||||
*
|
||||
* == Tag constants
|
||||
*
|
||||
* There is a constant defined for each universal tag:
|
||||
* * OpenSSL::ASN1::EOC (0)
|
||||
* * OpenSSL::ASN1::BOOLEAN (1)
|
||||
* * OpenSSL::ASN1::INTEGER (2)
|
||||
* * OpenSSL::ASN1::BIT_STRING (3)
|
||||
* * OpenSSL::ASN1::OCTET_STRING (4)
|
||||
* * OpenSSL::ASN1::NULL (5)
|
||||
* * OpenSSL::ASN1::OBJECT (6)
|
||||
* * OpenSSL::ASN1::ENUMERATED (10)
|
||||
* * OpenSSL::ASN1::UTF8STRING (12)
|
||||
* * OpenSSL::ASN1::SEQUENCE (16)
|
||||
* * OpenSSL::ASN1::SET (17)
|
||||
* * OpenSSL::ASN1::NUMERICSTRING (18)
|
||||
* * OpenSSL::ASN1::PRINTABLESTRING (19)
|
||||
* * OpenSSL::ASN1::T61STRING (20)
|
||||
* * OpenSSL::ASN1::VIDEOTEXSTRING (21)
|
||||
* * OpenSSL::ASN1::IA5STRING (22)
|
||||
* * OpenSSL::ASN1::UTCTIME (23)
|
||||
* * OpenSSL::ASN1::GENERALIZEDTIME (24)
|
||||
* * OpenSSL::ASN1::GRAPHICSTRING (25)
|
||||
* * OpenSSL::ASN1::ISO64STRING (26)
|
||||
* * OpenSSL::ASN1::GENERALSTRING (27)
|
||||
* * OpenSSL::ASN1::UNIVERSALSTRING (28)
|
||||
* * OpenSSL::ASN1::BMPSTRING (30)
|
||||
*
|
||||
* == UNIVERSAL_TAG_NAME constant
|
||||
*
|
||||
* An Array that stores the name of a given tag number. These names are
|
||||
* the same as the name of the tag constant that is additionally defined,
|
||||
* e.g. UNIVERSAL_TAG_NAME[2] = "INTEGER" and OpenSSL::ASN1::INTEGER = 2.
|
||||
*
|
||||
* == Example usage
|
||||
*
|
||||
* === Decoding and viewing a DER-encoded file
|
||||
* require 'openssl'
|
||||
* require 'pp'
|
||||
* der = File.binread('data.der')
|
||||
* asn1 = OpenSSL::ASN1.decode(der)
|
||||
* pp der
|
||||
*
|
||||
* === Creating an ASN.1 structure and DER-encoding it
|
||||
* require 'openssl'
|
||||
* version = OpenSSL::ASN1::Integer.new(1)
|
||||
* # Explicitly 0-tagged implies context-specific tag class
|
||||
* serial = OpenSSL::ASN1::Integer.new(12345, 0, :EXPLICIT, :CONTEXT_SPECIFIC)
|
||||
* name = OpenSSL::ASN1::PrintableString.new('Data 1')
|
||||
* sequence = OpenSSL::ASN1::Sequence.new( [ version, serial, name ] )
|
||||
* der = sequence.to_der
|
||||
*/
|
||||
mASN1 = rb_define_module_under(mOSSL, "ASN1");
|
||||
|
||||
/* Document-class: OpenSSL::ASN1::ASN1Error
|
||||
*
|
||||
* Generic error class for all errors raised in ASN1 and any of the
|
||||
* classes defined in it.
|
||||
*/
|
||||
eASN1Error = rb_define_class_under(mASN1, "ASN1Error", eOSSLError);
|
||||
rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
|
||||
rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
|
||||
rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);
|
||||
ary = rb_ary_new();
|
||||
|
||||
/*
|
||||
* Array storing tag names at the tag's index.
|
||||
*/
|
||||
rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary);
|
||||
for(i = 0; i < ossl_asn1_info_size; i++){
|
||||
if(ossl_asn1_info[i].name[0] == '[') continue;
|
||||
|
@ -1202,6 +1452,126 @@ Init_ossl_asn1()
|
|||
rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name));
|
||||
}
|
||||
|
||||
/* Document-class: OpenSSL::ASN1::ASN1Data
|
||||
*
|
||||
* The top-level class representing any ASN.1 object. When parsed by
|
||||
* ASN1#decode, tagged values are always represented by an instance
|
||||
* of ASN1Data.
|
||||
*
|
||||
* == Attributes
|
||||
*
|
||||
* === +value+
|
||||
*
|
||||
* Carries the value of a ASN.1 type.
|
||||
* Please confer Constructive and Primitive for the mappings between
|
||||
* ASN.1 data types and Ruby classes.
|
||||
*
|
||||
* === +tag+
|
||||
*
|
||||
* A +Number+ representing the tag number of this ASN1Data. Never +nil+.
|
||||
*
|
||||
* === +tag_class+
|
||||
*
|
||||
* A +Symbol+ reprensenting the tag class of this ASN1Data. Never +nil+.
|
||||
* See ASN1Data for possible values.
|
||||
*
|
||||
* === +infinite_length+
|
||||
*
|
||||
* Never +nil+. A Boolean indicating whether the encoding was infinite
|
||||
* length (in the case of parsing) or whether an infinite length encoding
|
||||
* shall be used (in the encoding case).
|
||||
* In DER, every value has a finite length associated with it. But in
|
||||
* scenarios where large amounts of data need to be transferred it
|
||||
* might be desirable to have some kind of streaming support available.
|
||||
* For example, huge OCTET STRINGs are preferrably sent in smaller-sized
|
||||
* chunks, each at a time.
|
||||
* This is possible in BER by setting the length bytes of an encoding
|
||||
* to zero and by this indicating that the following value will be
|
||||
* sent in chunks. Infinite length encodings are always constructed.
|
||||
* The end of such a stream of chunks is indicated by sending a EOC
|
||||
* (End of Content) tag. SETs and SEQUENCEs may use an infinite length
|
||||
* encoding, but also primitive types such as e.g. OCTET STRINGS or
|
||||
* BIT STRINGS may leverage this functionality (cf. ITU-T X.690).
|
||||
*
|
||||
* == The role of ASN1Data for parsing tagged values
|
||||
*
|
||||
* When encoding an ASN.1 type it is inherently clear what original
|
||||
* type a this value has, regardless of its tagging.
|
||||
* But opposed to the time when an ASN.1 type is to be encoded, when
|
||||
* parsing them it is not possible to deduce the "real type" of tagged
|
||||
* values. This is why tagged values are generally parsed into ASN1Data
|
||||
* instances, but with a different outcome for implicit and explicit
|
||||
* tagging.
|
||||
* === Example of a parsed implicitly tagged value
|
||||
*
|
||||
* An implicitly 1-tagged INTEGER value will be parsed as an
|
||||
* ASN1Data with
|
||||
* * +tag+ equal to 1
|
||||
* * +tag_class+ equal to +:CONTEXT_SPECIFIC+
|
||||
* * +value+ equal to a +String+ that carries the raw encoding
|
||||
* of the INTEGER.
|
||||
* This implies that a subsequent decoding step is required to
|
||||
* completely decode implicitly tagged values.
|
||||
*
|
||||
* === Example of a parsed explicitly tagged value
|
||||
*
|
||||
* An explicitly 1-tagged INTEGER value will be parsed as an
|
||||
* ASN1Data with
|
||||
* * +tag+ equal to 1
|
||||
* * +tag_class+ equal to +:CONTEXT_SPECIFIC+
|
||||
* * +value+ equal to an +Array+ with one single element, an
|
||||
* instance of OpenSSL::ASN1::Integer, i.e. the inner element
|
||||
* is the non-tagged primitive value, and the tagging is represented
|
||||
* in the outer ASN1Data
|
||||
*
|
||||
* == Example - Decoding an implicitly tagged INTEGER
|
||||
* int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) # implicit 0-tagged
|
||||
* seq = OpenSSL::ASN1::Sequence.new( [int] )
|
||||
* der = seq.to_der
|
||||
* asn1 = OpenSSL::ASN1.decode(der)
|
||||
* # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
|
||||
* # @infinite_length=false,
|
||||
* # @tag=16,
|
||||
* # @tag_class=:UNIVERSAL,
|
||||
* # @tagging=nil,
|
||||
* # @value=
|
||||
* # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
|
||||
* # @infinite_length=false,
|
||||
* # @tag=0,
|
||||
* # @tag_class=:CONTEXT_SPECIFIC,
|
||||
* # @value="\x01">]>
|
||||
* raw_int = asn1.value[0]
|
||||
* # manually rewrite tag and tag class to make it an UNIVERSAL value
|
||||
* raw_int.tag = OpenSSL::ASN1::INTEGER
|
||||
* raw_int.tag_class = :UNIVERSAL
|
||||
* int2 = OpenSSL::ASN1.decode(raw_int)
|
||||
* puts int2.value # => 1
|
||||
*
|
||||
* == Example - Decoding an explicitly tagged INTEGER
|
||||
* int = OpenSSL::ASN1::Integer.new(1, 0, :EXPLICIT) # explicit 0-tagged
|
||||
* seq = OpenSSL::ASN1::Sequence.new( [int] )
|
||||
* der = seq.to_der
|
||||
* asn1 = OpenSSL::ASN1.decode(der)
|
||||
* # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
|
||||
* # @infinite_length=false,
|
||||
* # @tag=16,
|
||||
* # @tag_class=:UNIVERSAL,
|
||||
* # @tagging=nil,
|
||||
* # @value=
|
||||
* # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
|
||||
* # @infinite_length=false,
|
||||
* # @tag=0,
|
||||
* # @tag_class=:CONTEXT_SPECIFIC,
|
||||
* # @value=
|
||||
* # [#<OpenSSL::ASN1::Integer:0x85bf308
|
||||
* # @infinite_length=false,
|
||||
* # @tag=2,
|
||||
* # @tag_class=:UNIVERSAL
|
||||
* # @tagging=nil,
|
||||
* # @value=1>]>]>
|
||||
* int2 = asn1.value[0].value[0]
|
||||
* puts int2.value # => 1
|
||||
*/
|
||||
cASN1Data = rb_define_class_under(mASN1, "ASN1Data", rb_cObject);
|
||||
rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
|
||||
rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
|
||||
|
@ -1210,12 +1580,137 @@ Init_ossl_asn1()
|
|||
rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
|
||||
rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
|
||||
|
||||
/* Document-class: OpenSSL::ASN1::Primitive
|
||||
*
|
||||
* The parent class for all primitive encodings. Attributes are the same as
|
||||
* for ASN1Data, with the addition of +tagging+. +tagging+ may be used
|
||||
* as a hint for encoding a value either implicitly or explicitly by
|
||||
* setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
|
||||
* +tagging+ is not set when a ASN.1 structure is parsed using
|
||||
* OpenSSL::ASN1.decode. * Primitive values can never be infinite length encodings, thus it is not
|
||||
* possible to set the +infinite_length+ attribute for Primitive and its
|
||||
* sub-classes.
|
||||
*
|
||||
* == Primitive sub-classes and their mapping to Ruby classes
|
||||
* * OpenSSL::ASN1::EndOfContent <=> +value+ is always +nil+
|
||||
* * OpenSSL::ASN1::Boolean <=> +value+ is a +Boolean+
|
||||
* * OpenSSL::ASN1::Integer <=> +value+ is a +Number+
|
||||
* * OpenSSL::ASN1::BitString <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::OctetString <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::Null <=> +value+ is always +nil+
|
||||
* * OpenSSL::ASN1::Object <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::Enumerated <=> +value+ is a +Number+
|
||||
* * OpenSSL::ASN1::UTF8String <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::NumericString <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::PrintableString <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::T61String <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::VideotexString <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::IA5String <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::UTCTime <=> +value+ is a +Time+
|
||||
* * OpenSSL::ASN1::GeneralizedTime <=> +value+ is a +Time+
|
||||
* * OpenSSL::ASN1::GraphicString <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::ISO64String <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::GeneralString <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::UniversalString <=> +value+ is a +String+
|
||||
* * OpenSSL::ASN1::BMPString <=> +value+ is a +String+
|
||||
*
|
||||
* == OpenSSL::ASN1::BitString
|
||||
*
|
||||
* === Additional attributes
|
||||
* +unused_bits+: if the underlying BIT STRING's
|
||||
* length is a multiple of 8 then +unused_bits+ is 0. Otherwise
|
||||
* +unused_bits+ indicates the number of bits that are to be ignored in
|
||||
* the final octet of the +BitString+'s +value+.
|
||||
*
|
||||
* == OpenSSL::ASN1::ObjectId
|
||||
*
|
||||
* === Additional attributes
|
||||
* * +sn+: the short name as defined in <openssl/objects.h>.
|
||||
* * +ln+: the long name as defined in <openssl/objects.h>.
|
||||
* * +oid+: the object identifier as a +String+, e.g. "1.2.3.4.5"
|
||||
* * +short_name+: alias for +sn+.
|
||||
* * +long_name+: alias for +ln+.
|
||||
*
|
||||
* == Examples
|
||||
* With the Exception of OpenSSL::ASN1::EndOfContent, each Primitive class
|
||||
* takes at least one parameter, the +value+.
|
||||
*
|
||||
* === Creating EndOfContent
|
||||
* eoc = OpenSSL::ASN1::EndOfContent.new
|
||||
*
|
||||
* === Creating any other Primitive
|
||||
* prim = <class>.new(value) # <class> being one of the sub-classes except EndOfContent
|
||||
* prim_zero_tagged_implicit = <class>.new(value, 0, :IMPLICIT)
|
||||
* prim_zero_tagged_explicit = <class>.new(value, 0, :EXPLICIT)
|
||||
*/
|
||||
cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data);
|
||||
rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
|
||||
rb_undef_method(cASN1Primitive, "infinite_length=");
|
||||
rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
|
||||
rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
|
||||
|
||||
/* Document-class: OpenSSL::ASN1::Constructive
|
||||
*
|
||||
* The parent class for all constructed encodings. The +value+ attribute
|
||||
* of a Constructive is always an +Array+. Attributes are the same as
|
||||
* for ASN1Data, with the addition of +tagging+. +tagging+ may be used
|
||||
* as a hint for encoding to encode a value either implicitly or
|
||||
* explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
|
||||
* +tagging+ is not set when a ASN.1 structure is parsed using
|
||||
* OpenSSL::ASN1.decode.
|
||||
*
|
||||
* == SET and SEQUENCE
|
||||
*
|
||||
* Most constructed encodings come in the form of a SET or a SEQUENCE.
|
||||
* These encodings are represented by one of the two sub-classes of
|
||||
* Constructive:
|
||||
* * OpenSSL::ASN1::Set
|
||||
* * OpenSSL::ASN1::Sequence
|
||||
* Please note that tagged sequences and sets are still parsed as
|
||||
* instances of ASN1Data. Find further details on tagged values
|
||||
* there.
|
||||
*
|
||||
* === Example - constructing a SEQUENCE
|
||||
* int = OpenSSL::ASN1::Integer.new(1)
|
||||
* str = OpenSSL::ASN1::PrintableString.new('abc')
|
||||
* sequence = OpenSSL::ASN1::Sequence.new( [ int, str ] )
|
||||
*
|
||||
* === Example - constructing a SET
|
||||
* int = OpenSSL::ASN1::Integer.new(1)
|
||||
* str = OpenSSL::ASN1::PrintableString.new('abc')
|
||||
* set = OpenSSL::ASN1::Set.new( [ int, str ] )
|
||||
*
|
||||
* == Infinite length primitive values
|
||||
*
|
||||
* The only case where Constructive is used directly is for infinite
|
||||
* length encodings of primitive values. These encodings are always
|
||||
* constructed, with the contents of the +value+ +Array+ being either
|
||||
* UNIVERSAL non-infinite length partial encodings of the actual value
|
||||
* or again constructive encodings with infinite length (i.e. infinite
|
||||
* length primitive encodings may be constructed recursively with another
|
||||
* infinite length value within an already infinite length value). Each
|
||||
* partial encoding must be of the same UNIVERSAL type as the overall
|
||||
* encoding. The value of the overall encoding consists of the
|
||||
* concatenation of each partial encoding taken in sequence. The +value+
|
||||
* array of the outer infinite length value must end with a
|
||||
* OpenSSL::ASN1::EndOfContent instance.
|
||||
*
|
||||
* === Example - Infinite length OCTET STRING
|
||||
* partial1 = OpenSSL::ASN1::OctetString.new("\x01")
|
||||
* partial2 = OpenSSL::ASN1::OctetString.new("\x02")
|
||||
* inf_octets = OpenSSL::ASN1::Constructive.new( [ partial1,
|
||||
* partial2,
|
||||
* OpenSSL::ASN1::EndOfContent.new ],
|
||||
* OpenSSL::ASN1::OCTET_STRING,
|
||||
* nil,
|
||||
* :UNIVERSAL )
|
||||
* # The real value of inf_octets is "\x01\x02", i.e. the concatenation
|
||||
* # of partial1 and partial2
|
||||
* inf_octets.infinite_length = true
|
||||
* der = inf_octets.to_der
|
||||
* asn1 = OpenSSL::ASN1.decode(der)
|
||||
* puts asn1.infinite_length # => true
|
||||
*/
|
||||
cASN1Constructive = rb_define_class_under(mASN1,"Constructive", cASN1Data);
|
||||
rb_include_module(cASN1Constructive, rb_mEnumerable);
|
||||
rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue);
|
||||
|
|
Loading…
Add table
Reference in a new issue