# 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 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 `true` or `false`

- OpenSSL::ASN1::Integer <=> value is an OpenSSL::BN

- 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 OpenSSL::BN

- 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¶ ↑

NOTE: While ::new will allocate a new ObjectId, it is not typically allocated this way, but rather that are received from 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.

## Examples¶ ↑

With the Exception of OpenSSL::ASN1::EndOfContent, each Primitive class constructor 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)

### Attributes

tagging[RW]

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.

### Public Class Methods

OpenSSL::ASN1::Primitive.new(value [, tag, tagging, tag_class ]) → Primitive click to toggle source

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)
    {
        VALUE value, tag, tagging, tag_class;
        int default_tag;

        rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
        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))
                ossl_raise(eASN1Error, "invalid tagging method");
            if(NIL_P(tag_class)) {
                if (NIL_P(tagging))
                    tag_class = sym_UNIVERSAL;
                else
                    tag_class = sym_CONTEXT_SPECIFIC;
            }
            if(!SYMBOL_P(tag_class))
                ossl_raise(eASN1Error, "invalid tag class");
        }
        else{
            tag = INT2NUM(default_tag);
            tagging = Qnil;
            tag_class = sym_UNIVERSAL;
        }
        ossl_asn1_set_tag(self, tag);
        ossl_asn1_set_value(self, value);
        ossl_asn1_set_tagging(self, tagging);
        ossl_asn1_set_tag_class(self, tag_class);
        ossl_asn1_set_indefinite_length(self, Qfalse);
        if (default_tag == V_ASN1_BIT_STRING)
            rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0));

        return self;
    }

### Public Instance Methods

to_der → DER-encoded String click to toggle source

See OpenSSL::ASN1::ASN1Data#to_der for details.

    static VALUE
    ossl_asn1prim_to_der(VALUE self)
    {
        ASN1_TYPE *asn1;
        long alllen, bodylen;
        unsigned char *p0, *p1;
        int j, tag, tc, state;
        VALUE str;

        if (ossl_asn1_default_tag(self) == -1) {
            str = ossl_asn1_get_value(self);
            return to_der_internal(self, 0, 0, StringValue(str));
        }

        asn1 = ossl_asn1_get_asn1type(self);
        alllen = i2d_ASN1_TYPE(asn1, NULL);
        if (alllen < 0) {
            ASN1_TYPE_free(asn1);
            ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
        }
        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);
        assert(p0 - p1 == alllen);

        /* 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));
    }