[前][次][番号順一覧][スレッド一覧]

ruby-changes:19543

From: emboss <ko1@a...>
Date: Mon, 16 May 2011 05:16:48 +0900 (JST)
Subject: [ruby-changes:19543] emboss:r31584 (trunk): * ext/openssl/ossl_asn1.c: Add documentation.

emboss	2011-05-16 05:15:38 +0900 (Mon, 16 May 2011)

  New Revision: 31584

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31584

  Log:
    * ext/openssl/ossl_asn1.c: Add documentation.
    
    Previous revision: 31583

  Modified files:
    trunk/ChangeLog
    trunk/ext/openssl/ossl_asn1.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31583)
+++ ChangeLog	(revision 31584)
@@ -1,3 +1,7 @@
+Mon May 16 05:13:20 2011  Martin Bosslet  <Martin.Bosslet@g...>
+
+	* ext/openssl/ossl_asn1.c: Add documentation.
+
 Mon May 16 00:32:05 2011  KOSAKI Motohiro  <kosaki.motohiro@g...>
 
 	* test/ruby/test_signal.rb (TestSignal#test_signal_process_group):
Index: ext/openssl/ossl_asn1.c
===================================================================
--- ext/openssl/ossl_asn1.c	(revision 31583)
+++ ext/openssl/ossl_asn1.c	(revision 31584)
@@ -655,6 +655,20 @@
 	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 @@
     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 @@
 
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
 	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 @@
     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);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]