aboutsummaryrefslogtreecommitdiffstats
path: root/ext/openssl/ossl_asn1.c
diff options
context:
space:
mode:
authorrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-03 12:35:27 +0000
committerrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-03 12:35:27 +0000
commitad3b68057f7a786ee1c22ae069b5eb3bfd79a995 (patch)
tree881cdacc3312e65261ebd34a807c75ee09fdb303 /ext/openssl/ossl_asn1.c
parentef1d26e5b0eb12208681e7b1504dabd3e9beeed7 (diff)
downloadruby-ad3b68057f7a786ee1c22ae069b5eb3bfd79a995.tar.gz
openssl: import v2.1.0.beta1
Import Ruby/OpenSSL 2.1.0.beta1. The full commit log since v2.0.5 (imported by r59567) can be found at: https://github.com/ruby/openssl/compare/v2.0.5...v2.1.0.beta1 ---------------------------------------------------------------- Antonio Terceiro (1): test/test_ssl: explicitly accept TLS 1.1 in corresponding test Colby Swandale (1): document using secure protocol to fetch git master in Bundler Colton Jenkins (1): Add fips_mode_get to return fips_mode Kazuki Yamaguchi (85): Start preparing for 2.1.0 Remove support for OpenSSL 0.9.8 and 1.0.0 bn: refine tests bn: implement unary {plus,minus} operators for OpenSSL::BN bn: implement OpenSSL::BN#negative? Don't define main() when built with --enable-debug test: let OpenSSL::TestCase include OpenSSL::TestUtils test: prepare test PKey instances on demand Add OpenSSL.print_mem_leaks Enable OSSL_MDEBUG on CI builds ssl: move default DH parameters from OpenSSL::PKey::DH Make exceptions with the same format regardless of OpenSSL.debug ssl: show reason of 'certificate verify error' in exception message ssl: remove OpenSSL::ExtConfig::TLS_DH_anon_WITH_AES_256_GCM_SHA384 ssl: do not confuse different ex_data index registries ssl: assume SSL/SSL_CTX always have a valid reference to the Ruby object Fix RDoc markup ssl: suppress compiler warning ext/openssl/deprecation.rb: remove broken-apple-openssl extconf.rb: print informative message if OpenSSL can't be found Rakefile: compile the extension before test kdf: introduce OpenSSL::KDF module ossl.h: add NUM2UINT64T() macro kdf: add scrypt Expand rb_define_copy_func() macro Expand FPTR_TO_FD() macro Remove SafeGet*() macros cipher: rename GetCipherPtr() to ossl_evp_get_cipherbyname() digest: rename GetDigestPtr() to ossl_evp_get_digestbyname() Add ossl_str_new(), an exception-safe rb_str_new() bio: simplify ossl_membio2str() using ossl_str_new() Remove unused functions and macros Drop support for LibreSSL 2.3 ocsp: add OpenSSL::OCSP::Request#signed? asn1: infinite length -> indefinite length asn1: rearrange tests ssl: remove a needless NULL check in SSL::SSLContext#ciphers ssl: return nil in SSL::SSLSocket#cipher if session is not started asn1: remove an unnecessary function prototype asn1: require tag information when instantiating generic type asn1: initialize 'unused_bits' attribute of BitString with 0 asn1: check for illegal 'unused_bits' value of BitString asn1: disallow NULL to be passed to asn1time_to_time() asn1: avoid truncating OID in OpenSSL::ASN1::ObjectId#oid asn1: allow constructed encoding with definite length form asn1: prohibit indefinite length form for primitive encoding asn1: allow tag number to be >= 32 for universal tag class asn1: use ossl_asn1_tag() asn1: clean up OpenSSL::ASN1::Constructive#to_der asn1: harmonize OpenSSL::ASN1::*#to_der asn1: prevent EOC octets from being in the middle of the content asn1: do not treat EOC octets as part of content octets x509name: add 'loc' and 'set' kwargs to OpenSSL::X509::Name#add_entry ssl: do not call session_remove_cb during GC Backport "Merge branch 'topic/test-memory-leak'" to maint cipher: update the documentation for Cipher#auth_tag= Rakefile: let sync:to_ruby know about test/openssl/fixtures test: fix formatting test/utils: remove OpenSSL::TestUtils.silent test/utils: add SSLTestCase#tls12_supported? test/utils: have start_server yield only the port number test/utils: do not set ecdh_curves in start_server test/utils: let server_loop close socket test/utils: improve error handling in start_server test/utils: add OpenSSL::TestUtils.openssl? and .libressl? test/utils: do not use DSA certificates in SSL tests test/test_ssl: remove test_invalid_shutdown_by_gc test/test_ssl: move test_multibyte_read_write to test_pair test/test_ssl_session: rearrange tests test/test_pair, test/test_ssl: fix for TLS 1.3 ssl: remove useless call to rb_thread_wait_fd() ssl: fix NPN support ssl: mark OpenSSL::SSL::SSLContext::DEFAULT_{1024,2048} as private ssl: use 2048-bit group in the default tmp_dh_cb ssl: ensure that SSL option flags are non-negative ssl: update OpenSSL::SSL::OP_* flags ssl: prefer TLS_method() over SSLv23_method() ssl: add SSLContext#min_version= and #max_version= ssl: rework SSLContext#ssl_version= test/test_x509name: change script encoding to ASCII-8BIT x509name: refactor OpenSSL::X509::Name#to_s x509name: add OpenSSL::X509::Name#to_utf8 x509name: add OpenSSL::X509::Name#inspect x509name: update regexp in OpenSSL::X509::Name.parse Ruby/OpenSSL 2.1.0.beta1 Marcus Stollsteimer (1): Fix rdoc for core Integer class nobu (4): [DOC] {read,write}_nonblock with exception: false [DOC] keyword argument _exception_ [DOC] mark up literals Revert r57690 except for read_nonblock git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59734 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl/ossl_asn1.c')
-rw-r--r--ext/openssl/ossl_asn1.c660
1 files changed, 287 insertions, 373 deletions
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c
index 1d3ee4ac18..efa6b78742 100644
--- a/ext/openssl/ossl_asn1.c
+++ b/ext/openssl/ossl_asn1.c
@@ -9,11 +9,9 @@
*/
#include "ossl.h"
-static VALUE join_der(VALUE enumerable);
static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
int depth, int yield, long *num_read);
static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
-static VALUE ossl_asn1eoc_initialize(VALUE self);
/*
* DATE conversion
@@ -25,7 +23,6 @@ asn1time_to_time(const ASN1_TIME *time)
VALUE argv[6];
int count;
- if (!time || !time->data) return Qnil;
memset(&tm, 0, sizeof(struct tm));
switch (time->type) {
@@ -72,7 +69,6 @@ asn1time_to_time(const ASN1_TIME *time)
return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv);
}
-#if defined(HAVE_ASN1_TIME_ADJ)
void
ossl_time_split(VALUE time, time_t *sec, int *days)
{
@@ -88,13 +84,6 @@ ossl_time_split(VALUE time, time_t *sec, int *days)
*sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400)));
}
}
-#else
-time_t
-time_to_time_t(VALUE time)
-{
- return (time_t)NUM2TIMET(rb_Integer(time));
-}
-#endif
/*
* STRING conversion
@@ -155,13 +144,13 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
-#define ossl_asn1_get_infinite_length(o) rb_attr_get((o),sivINFINITE_LENGTH)
+#define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH)
#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
-#define ossl_asn1_set_infinite_length(o,v) rb_ivar_set((o),sivINFINITE_LENGTH,(v))
+#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v))
VALUE mASN1;
VALUE eASN1Error;
@@ -187,7 +176,7 @@ VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
static VALUE sym_IMPLICIT, sym_EXPLICIT;
static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
-static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINFINITE_LENGTH, sivUNUSED_BITS;
+static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS;
static ID id_each;
/*
@@ -213,13 +202,15 @@ obj_to_asn1bstr(VALUE obj, long unused_bits)
{
ASN1_BIT_STRING *bstr;
- if(unused_bits < 0) unused_bits = 0;
+ if (unused_bits < 0 || unused_bits > 7)
+ ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\
+ "the range 0 to 7");
StringValue(obj);
if(!(bstr = ASN1_BIT_STRING_new()))
ossl_raise(eASN1Error, NULL);
ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj));
bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
- bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07);
+ bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
return bstr;
}
@@ -269,15 +260,10 @@ obj_to_asn1utime(VALUE time)
time_t sec;
ASN1_UTCTIME *t;
-#if defined(HAVE_ASN1_TIME_ADJ)
int off_days;
ossl_time_split(time, &sec, &off_days);
if (!(t = ASN1_UTCTIME_adj(NULL, sec, off_days, 0)))
-#else
- sec = time_to_time_t(time);
- if (!(t = ASN1_UTCTIME_set(NULL, sec)))
-#endif
ossl_raise(eASN1Error, NULL);
return t;
@@ -289,15 +275,10 @@ obj_to_asn1gtime(VALUE time)
time_t sec;
ASN1_GENERALIZEDTIME *t;
-#if defined(HAVE_ASN1_TIME_ADJ)
int off_days;
ossl_time_split(time, &sec, &off_days);
if (!(t = ASN1_GENERALIZEDTIME_adj(NULL, sec, off_days, 0)))
-#else
- sec = time_to_time_t(time);
- if (!(t = ASN1_GENERALIZEDTIME_set(NULL, sec)))
-#endif
ossl_raise(eASN1Error, NULL);
return t;
@@ -517,7 +498,7 @@ ossl_asn1_get_asn1type(VALUE obj)
VALUE value, rflag;
void *ptr;
void (*free_func)();
- int tag, flag;
+ int tag;
tag = ossl_asn1_default_tag(obj);
value = ossl_asn1_get_value(obj);
@@ -533,8 +514,7 @@ ossl_asn1_get_asn1type(VALUE obj)
break;
case V_ASN1_BIT_STRING:
rflag = rb_attr_get(obj, sivUNUSED_BITS);
- flag = NIL_P(rflag) ? -1 : NUM2INT(rflag);
- ptr = obj_to_asn1bstr(value, flag);
+ ptr = obj_to_asn1bstr(value, NUM2INT(rflag));
free_func = ASN1_BIT_STRING_free;
break;
case V_ASN1_NULL:
@@ -598,8 +578,8 @@ ossl_asn1_default_tag(VALUE obj)
return NUM2INT(tag);
tmp_class = rb_class_superclass(tmp_class);
}
- ossl_raise(eASN1Error, "universal tag for %"PRIsVALUE" not found",
- rb_obj_class(obj));
+
+ return -1;
}
static int
@@ -615,20 +595,6 @@ ossl_asn1_tag(VALUE obj)
}
static int
-ossl_asn1_is_explicit(VALUE obj)
-{
- VALUE s;
-
- s = ossl_asn1_get_tagging(obj);
- if (NIL_P(s) || s == sym_IMPLICIT)
- return 0;
- else if (s == sym_EXPLICIT)
- return 1;
- else
- ossl_raise(eASN1Error, "invalid tag default");
-}
-
-static int
ossl_asn1_tag_class(VALUE obj)
{
VALUE s;
@@ -663,12 +629,12 @@ ossl_asn1_class2sym(int tc)
* call-seq:
* OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) => ASN1Data
*
- * +value+: Please have a look at Constructive and Primitive to see how Ruby
+ * _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_: An Integer indicating the tag number.
*
- * +tag_class+: A +Symbol+ indicating the tag class. Please cf. ASN1 for
+ * _tag_class_: A Symbol indicating the tag class. Please cf. ASN1 for
* possible values.
*
* == Example
@@ -680,73 +646,85 @@ ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
{
if(!SYMBOL_P(tag_class))
ossl_raise(eASN1Error, "invalid tag class");
- if (tag_class == sym_UNIVERSAL && NUM2INT(tag) > 31)
- ossl_raise(eASN1Error, "tag number for Universal too large");
ossl_asn1_set_tag(self, tag);
ossl_asn1_set_value(self, value);
ossl_asn1_set_tag_class(self, tag_class);
- ossl_asn1_set_infinite_length(self, Qfalse);
+ ossl_asn1_set_indefinite_length(self, Qfalse);
return self;
}
static VALUE
-join_der_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, str))
+to_der_internal(VALUE self, int constructed, int indef_len, VALUE body)
{
- i = ossl_to_der_if_possible(i);
- StringValue(i);
- rb_str_append(str, i);
- return Qnil;
-}
+ int encoding = constructed ? indef_len ? 2 : 1 : 0;
+ int tag_class = ossl_asn1_tag_class(self);
+ int tag_number = ossl_asn1_tag(self);
+ int default_tag_number = ossl_asn1_default_tag(self);
+ int body_length, total_length;
+ VALUE str;
+ unsigned char *p;
-static VALUE
-join_der(VALUE enumerable)
-{
- VALUE str = rb_str_new(0, 0);
- rb_block_call(enumerable, id_each, 0, 0, join_der_i, str);
+ body_length = RSTRING_LENINT(body);
+ if (ossl_asn1_get_tagging(self) == sym_EXPLICIT) {
+ int inner_length, e_encoding = indef_len ? 2 : 1;
+
+ if (default_tag_number == -1)
+ ossl_raise(eASN1Error, "explicit tagging of unknown tag");
+
+ inner_length = ASN1_object_size(encoding, body_length, default_tag_number);
+ total_length = ASN1_object_size(e_encoding, inner_length, tag_number);
+ str = rb_str_new(NULL, total_length);
+ p = (unsigned char *)RSTRING_PTR(str);
+ /* Put explicit tag */
+ ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class);
+ /* Append inner object */
+ ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL);
+ memcpy(p, RSTRING_PTR(body), body_length);
+ p += body_length;
+ if (indef_len) {
+ ASN1_put_eoc(&p); /* For inner object */
+ ASN1_put_eoc(&p); /* For wrapper object */
+ }
+ }
+ else {
+ total_length = ASN1_object_size(encoding, body_length, tag_number);
+ str = rb_str_new(NULL, total_length);
+ p = (unsigned char *)RSTRING_PTR(str);
+ ASN1_put_object(&p, encoding, body_length, tag_number, tag_class);
+ memcpy(p, RSTRING_PTR(body), body_length);
+ p += body_length;
+ if (indef_len)
+ ASN1_put_eoc(&p);
+ }
+ assert(p - (unsigned char *)RSTRING_PTR(str) == total_length);
return str;
}
+static VALUE ossl_asn1prim_to_der(VALUE);
+static VALUE ossl_asn1cons_to_der(VALUE);
/*
* 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.
+ * DER-encoded except for the possibility of indefinite length forms.
+ * Indefinite length forms 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)
{
- VALUE value, der, inf_length;
- int tag, tag_class, is_cons = 0;
- long length;
- unsigned char *p;
-
- value = ossl_asn1_get_value(self);
- if(rb_obj_is_kind_of(value, rb_cArray)){
- is_cons = 1;
- value = join_der(value);
- }
- StringValue(value);
+ VALUE value = ossl_asn1_get_value(self);
- tag = ossl_asn1_tag(self);
- tag_class = ossl_asn1_tag_class(self);
- inf_length = ossl_asn1_get_infinite_length(self);
- if (inf_length == Qtrue) {
- is_cons = 2;
+ if (rb_obj_is_kind_of(value, rb_cArray))
+ return ossl_asn1cons_to_der(self);
+ else {
+ if (RTEST(ossl_asn1_get_indefinite_length(self)))
+ ossl_raise(eASN1Error, "indefinite length form cannot be used " \
+ "with primitive encoding");
+ return ossl_asn1prim_to_der(self);
}
- if((length = ASN1_object_size(is_cons, RSTRING_LENINT(value), tag)) <= 0)
- ossl_raise(eASN1Error, NULL);
- der = rb_str_new(0, length);
- p = (unsigned char *)RSTRING_PTR(der);
- ASN1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class);
- memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
- p += RSTRING_LEN(value);
- ossl_str_adjust(der, p);
-
- return der;
}
static VALUE
@@ -829,46 +807,33 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
int tag, VALUE tc, long *num_read)
{
VALUE value, asn1data, ary;
- int infinite;
+ int indefinite;
long available_len, off = *offset;
- infinite = (j == 0x21);
+ indefinite = (j == 0x21);
ary = rb_ary_new();
- available_len = infinite ? max_len : length;
+ available_len = indefinite ? max_len : length;
while (available_len > 0) {
long inner_read = 0;
value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read);
*num_read += inner_read;
available_len -= inner_read;
- rb_ary_push(ary, value);
- if (infinite &&
- NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC &&
+ if (indefinite &&
+ ossl_asn1_tag(value) == V_ASN1_EOC &&
ossl_asn1_get_tag_class(value) == sym_UNIVERSAL) {
break;
}
+ rb_ary_push(ary, value);
}
if (tc == sym_UNIVERSAL) {
VALUE args[4];
- int not_sequence_or_set;
-
- not_sequence_or_set = tag != V_ASN1_SEQUENCE && tag != V_ASN1_SET;
-
- if (not_sequence_or_set) {
- if (infinite) {
- asn1data = rb_obj_alloc(cASN1Constructive);
- }
- else {
- ossl_raise(eASN1Error, "invalid non-infinite tag");
- return Qnil;
- }
- }
- else {
- VALUE klass = *ossl_asn1_info[tag].klass;
- asn1data = rb_obj_alloc(klass);
- }
+ if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET)
+ asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass);
+ else
+ asn1data = rb_obj_alloc(cASN1Constructive);
args[0] = ary;
args[1] = INT2NUM(tag);
args[2] = Qnil;
@@ -880,10 +845,10 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc);
}
- if (infinite)
- ossl_asn1_set_infinite_length(asn1data, Qtrue);
+ if (indefinite)
+ ossl_asn1_set_indefinite_length(asn1data, Qtrue);
else
- ossl_asn1_set_infinite_length(asn1data, Qfalse);
+ ossl_asn1_set_indefinite_length(asn1data, Qfalse);
*offset = off;
return asn1data;
@@ -936,7 +901,8 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
inner_read += hlen;
}
else {
- if ((j & 0x01) && (len == 0)) ossl_raise(eASN1Error, "Infinite length for primitive value");
+ if ((j & 0x01) && (len == 0))
+ ossl_raise(eASN1Error, "indefinite length for primitive value");
asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read);
off += hlen + len;
}
@@ -968,13 +934,13 @@ int_ossl_decode_sanity_check(long len, long read, long offset)
*
* 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)
+ * * depth: The recursion depth, plus one with each constructed value being encountered (Integer)
+ * * offset: Current byte offset (Integer)
+ * * header length: Combined length in bytes of the Tag and Length headers. (Integer)
+ * * length: The overall remaining length of the entire data (Integer)
* * constructed: Whether this value is constructed or not (Boolean)
* * tag_class: Current tag class (Symbol)
- * * tag: The current tag (Number)
+ * * tag: The current tag number (Integer)
*
* == Example
* der = File.binread('asn1data.der')
@@ -1004,9 +970,9 @@ ossl_asn1_traverse(VALUE self, VALUE obj)
* 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+.
+ * 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')
@@ -1034,9 +1000,9 @@ ossl_asn1_decode(VALUE self, VALUE obj)
* 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+
+ * 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
@@ -1071,19 +1037,19 @@ ossl_asn1_decode_all(VALUE self, VALUE obj)
/*
* call-seq:
- * OpenSSL::ASN1::Primitive.new( value [, tag, tagging, tag_class ]) => Primitive
+ * OpenSSL::ASN1::Primitive.new(value [, tag, tagging, tag_class ]) => Primitive
*
- * +value+: is mandatory.
+ * _value_: is mandatory.
*
- * +tag+: optional, may be specified for tagged values. If no +tag+ is
+ * _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
+ * _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
+ * _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.
*
@@ -1096,9 +1062,12 @@ static VALUE
ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE value, tag, tagging, tag_class;
+ int default_tag;
rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
- if(argc > 1){
+ default_tag = ossl_asn1_default_tag(self);
+
+ if (default_tag == -1 || argc > 1) {
if(NIL_P(tag))
ossl_raise(eASN1Error, "must specify tag number");
if(!NIL_P(tagging) && !SYMBOL_P(tagging))
@@ -1111,11 +1080,9 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
}
if(!SYMBOL_P(tag_class))
ossl_raise(eASN1Error, "invalid tag class");
- if (tagging == sym_IMPLICIT && NUM2INT(tag) > 31)
- ossl_raise(eASN1Error, "tag number for Universal too large");
}
else{
- tag = INT2NUM(ossl_asn1_default_tag(self));
+ tag = INT2NUM(default_tag);
tagging = Qnil;
tag_class = sym_UNIVERSAL;
}
@@ -1123,7 +1090,9 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
ossl_asn1_set_value(self, value);
ossl_asn1_set_tagging(self, tagging);
ossl_asn1_set_tag_class(self, tag_class);
- ossl_asn1_set_infinite_length(self, Qfalse);
+ ossl_asn1_set_indefinite_length(self, Qfalse);
+ if (default_tag == V_ASN1_BIT_STRING)
+ rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0));
return self;
}
@@ -1131,7 +1100,7 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_asn1eoc_initialize(VALUE self) {
VALUE tag, tagging, tag_class, value;
- tag = INT2NUM(ossl_asn1_default_tag(self));
+ tag = INT2FIX(0);
tagging = Qnil;
tag_class = sym_UNIVERSAL;
value = rb_str_new("", 0);
@@ -1139,51 +1108,58 @@ ossl_asn1eoc_initialize(VALUE self) {
ossl_asn1_set_value(self, value);
ossl_asn1_set_tagging(self, tagging);
ossl_asn1_set_tag_class(self, tag_class);
- ossl_asn1_set_infinite_length(self, Qfalse);
+ ossl_asn1_set_indefinite_length(self, Qfalse);
return self;
}
+static VALUE
+ossl_asn1eoc_to_der(VALUE self)
+{
+ return rb_str_new("\0\0", 2);
+}
+
/*
* call-seq:
* asn1.to_der => DER-encoded String
*
- * See ASN1Data#to_der for details. *
+ * See ASN1Data#to_der for details.
*/
static VALUE
ossl_asn1prim_to_der(VALUE self)
{
ASN1_TYPE *asn1;
- int tn, tc, explicit;
- long len, reallen;
- unsigned char *buf, *p;
+ long alllen, bodylen;
+ unsigned char *p0, *p1;
+ int j, tag, tc, state;
VALUE str;
- tn = NUM2INT(ossl_asn1_get_tag(self));
- tc = ossl_asn1_tag_class(self);
- explicit = ossl_asn1_is_explicit(self);
- asn1 = ossl_asn1_get_asn1type(self);
+ if (ossl_asn1_default_tag(self) == -1) {
+ str = ossl_asn1_get_value(self);
+ return to_der_internal(self, 0, 0, StringValue(str));
+ }
- len = ASN1_object_size(1, i2d_ASN1_TYPE(asn1, NULL), tn);
- if(!(buf = OPENSSL_malloc(len))){
+ asn1 = ossl_asn1_get_asn1type(self);
+ alllen = i2d_ASN1_TYPE(asn1, NULL);
+ if (alllen < 0) {
ASN1_TYPE_free(asn1);
- ossl_raise(eASN1Error, "cannot alloc buffer");
+ ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
}
- p = buf;
- if (tc == V_ASN1_UNIVERSAL) {
- i2d_ASN1_TYPE(asn1, &p);
- } else if (explicit) {
- ASN1_put_object(&p, 1, i2d_ASN1_TYPE(asn1, NULL), tn, tc);
- i2d_ASN1_TYPE(asn1, &p);
- } else {
- i2d_ASN1_TYPE(asn1, &p);
- *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
+ str = ossl_str_new(NULL, alllen, &state);
+ if (state) {
+ ASN1_TYPE_free(asn1);
+ rb_jump_tag(state);
}
+ p0 = p1 = (unsigned char *)RSTRING_PTR(str);
+ i2d_ASN1_TYPE(asn1, &p0);
ASN1_TYPE_free(asn1);
- reallen = p - buf;
- assert(reallen <= len);
- str = ossl_buf2str((char *)buf, rb_long2int(reallen)); /* buf will be free in ossl_buf2str */
+ assert(p0 - p1 == alllen);
- return str;
+ /* Strip header since to_der_internal() wants only the payload */
+ j = ASN1_get_object((const unsigned char **)&p1, &bodylen, &tag, &tc, alllen);
+ if (j & 0x80)
+ ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */
+
+ return to_der_internal(self, 0, 0, rb_str_drop_bytes(str, alllen - bodylen));
}
/*
@@ -1195,92 +1171,41 @@ ossl_asn1prim_to_der(VALUE self)
static VALUE
ossl_asn1cons_to_der(VALUE self)
{
- int tag, tn, tc, explicit, constructed = 1;
- int found_prim = 0, seq_len;
- long length;
- unsigned char *p;
- VALUE value, str, inf_length;
-
- tn = NUM2INT(ossl_asn1_get_tag(self));
- tc = ossl_asn1_tag_class(self);
- inf_length = ossl_asn1_get_infinite_length(self);
- if (inf_length == Qtrue) {
- VALUE ary, example;
- constructed = 2;
- if (rb_obj_class(self) == cASN1Sequence ||
- rb_obj_class(self) == cASN1Set) {
- tag = ossl_asn1_default_tag(self);
- }
- else { /* must be a constructive encoding of a primitive value */
- ary = ossl_asn1_get_value(self);
- if (!rb_obj_is_kind_of(ary, rb_cArray))
- ossl_raise(eASN1Error, "Constructive value must be an Array");
- /* Recursively descend until a primitive value is found.
- The overall value of the entire constructed encoding
- is of the type of the first primitive encoding to be
- found. */
- while (!found_prim){
- example = rb_ary_entry(ary, 0);
- if (rb_obj_is_kind_of(example, cASN1Primitive)){
- found_prim = 1;
- }
- else {
- /* example is another ASN1Constructive */
- if (!rb_obj_is_kind_of(example, cASN1Constructive)){
- ossl_raise(eASN1Error, "invalid constructed encoding");
- return Qnil; /* dummy */
- }
- ary = ossl_asn1_get_value(example);
- }
- }
- tag = ossl_asn1_default_tag(example);
- }
- }
- else {
- if (rb_obj_class(self) == cASN1Constructive)
- ossl_raise(eASN1Error, "Constructive shall only be used with infinite length");
- tag = ossl_asn1_default_tag(self);
- }
- explicit = ossl_asn1_is_explicit(self);
- value = join_der(ossl_asn1_get_value(self));
-
- seq_len = ASN1_object_size(constructed, RSTRING_LENINT(value), tag);
- length = ASN1_object_size(constructed, seq_len, tn);
- str = rb_str_new(0, length);
- p = (unsigned char *)RSTRING_PTR(str);
- if(tc == V_ASN1_UNIVERSAL)
- ASN1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
- else{
- if(explicit){
- ASN1_put_object(&p, constructed, seq_len, tn, tc);
- ASN1_put_object(&p, constructed, RSTRING_LENINT(value), tag, V_ASN1_UNIVERSAL);
- }
- else{
- ASN1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
+ VALUE ary, str;
+ long i;
+ int indef_len;
+
+ indef_len = RTEST(ossl_asn1_get_indefinite_length(self));
+ ary = rb_convert_type(ossl_asn1_get_value(self), T_ARRAY, "Array", "to_a");
+ str = rb_str_new(NULL, 0);
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ VALUE item = RARRAY_AREF(ary, i);
+
+ if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) {
+ if (i != RARRAY_LEN(ary) - 1)
+ ossl_raise(eASN1Error, "illegal EOC octets in value");
+
+ /*
+ * EOC is not really part of the content, but we required to add one
+ * at the end in the past.
+ */
+ break;
}
- }
- memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
- p += RSTRING_LEN(value);
- /* In this case we need an additional EOC (one for the explicit part and
- * one for the Constructive itself. The EOC for the Constructive is
- * supplied by the user, but that for the "explicit wrapper" must be
- * added here.
- */
- if (explicit && inf_length == Qtrue) {
- ASN1_put_eoc(&p);
+ item = ossl_to_der_if_possible(item);
+ StringValue(item);
+ rb_str_append(str, item);
}
- ossl_str_adjust(str, p);
- return str;
+ return to_der_internal(self, 1, indef_len, 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
+ * Calls the given block once for each element in self, passing that element
+ * as parameter _asn1_. If no block is given, an enumerator is returned
* instead.
*
* == Example
@@ -1300,8 +1225,8 @@ ossl_asn1cons_each(VALUE self)
* call-seq:
* OpenSSL::ASN1::ObjectId.register(object_id, short_name, long_name)
*
- * This adds a new ObjectId to the internal tables. Where +object_id+ is the
- * numerical form, +short_name+ is the short name, and +long_name+ is the long
+ * This adds a new ObjectId to the internal tables. Where _object_id_ is the
+ * numerical form, _short_name_ is the short name, and _long_name_ is the long
* name.
*
* Returns +true+ if successful. Raises an OpenSSL::ASN1::ASN1Error if it fails.
@@ -1320,14 +1245,13 @@ ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
return Qtrue;
}
-/* Document-method: OpenSSL::ASN1::ObjectId#sn
+/*
+ * call-seq:
+ * oid.sn -> string
+ * oid.short_name -> string
*
* The short name of the ObjectId, as defined in <openssl/objects.h>.
*/
-/* Document-method: OpenSSL::ASN1::ObjectId#short_name
- *
- * +short_name+ is an alias to +sn+
- */
static VALUE
ossl_asn1obj_get_sn(VALUE self)
{
@@ -1341,14 +1265,13 @@ ossl_asn1obj_get_sn(VALUE self)
return ret;
}
-/* Document-method: OpenSSL::ASN1::ObjectId#ln
+/*
+ * call-seq:
+ * oid.ln -> string
+ * oid.long_name -> string
*
* The long name of the ObjectId, as defined in <openssl/objects.h>.
*/
-/* Document-method: OpenSSL::ASN1::ObjectId#long_name
- *
- * +long_name+ is an alias to +ln+
- */
static VALUE
ossl_asn1obj_get_ln(VALUE self)
{
@@ -1362,23 +1285,48 @@ ossl_asn1obj_get_ln(VALUE self)
return ret;
}
-/* Document-method: OpenSSL::ASN1::ObjectId#oid
+static VALUE
+asn1obj_get_oid_i(VALUE vobj)
+{
+ ASN1_OBJECT *a1obj = (void *)vobj;
+ VALUE str;
+ int len;
+
+ str = rb_usascii_str_new(NULL, 127);
+ len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1);
+ if (len <= 0 || len == INT_MAX)
+ ossl_raise(eASN1Error, "OBJ_obj2txt");
+ if (len > RSTRING_LEN(str)) {
+ /* +1 is for the \0 terminator added by OBJ_obj2txt() */
+ rb_str_resize(str, len + 1);
+ len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1);
+ if (len <= 0)
+ ossl_raise(eASN1Error, "OBJ_obj2txt");
+ }
+ rb_str_set_len(str, len);
+ return str;
+}
+
+/*
+ * call-seq:
+ * oid.oid -> string
*
- * The object identifier as a +String+, e.g. "1.2.3.4.5"
+ * Returns a String representing the Object Identifier in the dot notation,
+ * e.g. "1.2.3.4.5"
*/
static VALUE
ossl_asn1obj_get_oid(VALUE self)
{
- VALUE val;
+ VALUE str;
ASN1_OBJECT *a1obj;
- char buf[128];
+ int state;
- val = ossl_asn1_get_value(self);
- a1obj = obj_to_asn1obj(val);
- OBJ_obj2txt(buf, sizeof(buf), a1obj, 1);
+ a1obj = obj_to_asn1obj(ossl_asn1_get_value(self));
+ str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state);
ASN1_OBJECT_free(a1obj);
-
- return rb_str_new2(buf);
+ if (state)
+ rb_jump_tag(state);
+ return str;
}
#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
@@ -1431,7 +1379,7 @@ Init_ossl_asn1(void)
sivTAG = rb_intern("@tag");
sivTAGGING = rb_intern("@tagging");
sivTAG_CLASS = rb_intern("@tag_class");
- sivINFINITE_LENGTH = rb_intern("@infinite_length");
+ sivINDEFINITE_LENGTH = rb_intern("@indefinite_length");
sivUNUSED_BITS = rb_intern("@unused_bits");
/*
@@ -1457,24 +1405,21 @@ Init_ossl_asn1(void)
* == ASN.1 class hierarchy
*
* The base class representing ASN.1 structures 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
+ * 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
+ * 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.
+ * opposed to "primitive" encodings with just one single value. The value of
+ * an Constructive is always an Array.
*
* ==== ASN1::Set and ASN1::Sequence
*
@@ -1491,18 +1436,18 @@ Init_ossl_asn1(void)
* Please cf. Primitive documentation for details on sub-classes and
* their respective mappings of ASN.1 data types to Ruby objects.
*
- * == Possible values for +tagging+
+ * == Possible values for _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
+ * 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+
+ * == 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+
+ * 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)
@@ -1604,9 +1549,9 @@ Init_ossl_asn1(void)
*
* 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
+ * * _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.
@@ -1615,9 +1560,9 @@ Init_ossl_asn1(void)
*
* 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
+ * * _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
@@ -1628,13 +1573,13 @@ Init_ossl_asn1(void)
* der = seq.to_der
* asn1 = OpenSSL::ASN1.decode(der)
* # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=16,
* # @tag_class=:UNIVERSAL,
* # @tagging=nil,
* # @value=
* # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=0,
* # @tag_class=:CONTEXT_SPECIFIC,
* # @value="\x01">]>
@@ -1651,18 +1596,18 @@ Init_ossl_asn1(void)
* der = seq.to_der
* asn1 = OpenSSL::ASN1.decode(der)
* # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=16,
* # @tag_class=:UNIVERSAL,
* # @tagging=nil,
* # @value=
* # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=0,
* # @tag_class=:CONTEXT_SPECIFIC,
* # @value=
* # [#<OpenSSL::ASN1::Integer:0x85bf308
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=2,
* # @tag_class=:UNIVERSAL
* # @tagging=nil,
@@ -1678,73 +1623,75 @@ Init_ossl_asn1(void)
*/
rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
/*
- * A +Number+ representing the tag number of this ASN1Data. Never +nil+.
+ * An Integer representing the tag number of this ASN1Data. Never +nil+.
*/
rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
/*
- * A +Symbol+ representing the tag class of this ASN1Data. Never +nil+.
+ * A Symbol representing the tag class of this ASN1Data. Never +nil+.
* See ASN1Data for possible values.
*/
rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
/*
- * 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.
+ * Never +nil+. A boolean value indicating whether the encoding uses
+ * indefinite length (in the case of parsing) or whether an indefinite
+ * length form shall be used (in the encoding case).
+ * In DER, every value uses definite length form. 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 preferably 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.
+ * sent in chunks. Indefinite 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
+ * (End of Content) tag. SETs and SEQUENCEs may use an indefinite length
* encoding, but also primitive types such as e.g. OCTET STRINGS or
* BIT STRINGS may leverage this functionality (cf. ITU-T X.690).
*/
- rb_attr(cASN1Data, rb_intern("infinite_length"), 1, 1, 0);
+ rb_attr(cASN1Data, rb_intern("indefinite_length"), 1, 1, 0);
+ rb_define_alias(cASN1Data, "infinite_length", "indefinite_length");
+ rb_define_alias(cASN1Data, "infinite_length=", "indefinite_length=");
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+.
- * 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.
+ * for ASN1Data, with the addition of _tagging_.
+ * Primitive values can never be encoded with indefinite length form, thus
+ * it is not possible to set the _indefinite_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::EndOfContent <=> _value_ is always +nil+
+ * * OpenSSL::ASN1::Boolean <=> _value_ is +true+ or +false+
+ * * OpenSSL::ASN1::Integer <=> _value_ is an Integer
+ * * 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 an Integer
+ * * 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+.
+ * _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
*
@@ -1753,15 +1700,15 @@ Init_ossl_asn1(void)
* parsed ASN1 encodings.
*
* === 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+.
+ * * _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
- * constructor takes at least one parameter, the +value+.
+ * constructor takes at least one parameter, the _value_.
*
* === Creating EndOfContent
* eoc = OpenSSL::ASN1::EndOfContent.new
@@ -1775,19 +1722,20 @@ Init_ossl_asn1(void)
/*
* 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
+ * _tagging_ is not set when a ASN.1 structure is parsed using
* OpenSSL::ASN1.decode.
*/
rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
+ rb_undef_method(cASN1Primitive, "indefinite_length=");
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+.
+ * 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_.
*
* == SET and SEQUENCE
*
@@ -1809,48 +1757,13 @@ Init_ossl_asn1(void)
* 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.
- *
- * Please note that it is not possible to encode Constructive without
- * the +infinite_length+ attribute being set to +true+, use
- * OpenSSL::ASN1::Sequence or OpenSSL::ASN1::Set in these cases instead.
- *
- * === 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);
/*
* 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
+ * _tagging_ is not set when a ASN.1 structure is parsed using
* OpenSSL::ASN1.decode.
*/
rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue);
@@ -1907,6 +1820,7 @@ do{\
rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
+ rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0);
class_tag_map = rb_hash_new();
rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));