An X.509 name represents a hostname, email address or other entity associated with a public key.
You can create a Name
by parsing a distinguished name String
or by supplying the distinguished name as an Array
.
name = OpenSSL::X509::Name.parse_rfc2253 'DC=example,CN=nobody' name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]
The default object type for name entries.
The default object type template for name entries.
static VALUE
ossl_x509name_initialize(int argc, VALUE *argv, VALUE self)
{
X509_NAME *name;
VALUE arg, template;
GetX509Name(self, name);
if (rb_scan_args(argc, argv, "02", &arg, &template) == 0) {
return self;
}
else {
VALUE tmp = rb_check_array_type(arg);
if (!NIL_P(tmp)) {
VALUE args;
if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE;
args = rb_ary_new3(2, self, template);
rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args);
}
else{
const unsigned char *p;
VALUE str = ossl_to_der_if_possible(arg);
X509_NAME *x;
StringValue(str);
p = (unsigned char *)RSTRING_PTR(str);
x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str));
DATA_PTR(self) = name;
if(!x){
ossl_raise(eX509NameError, NULL);
}
}
}
return self;
}
Creates a new Name
.
A name may be created from a DER encoded string der, an Array
representing a distinguished_name or a distinguished_name along with a template.
name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']] name = OpenSSL::X509::Name.new name.to_der
See add_entry
for a description of the distinguished_name Array’s contents
# File tmp/rubies/ruby-3.2.0/ext/openssl/lib/openssl/x509.rb, line 305
def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
if str.start_with?("/")
# /A=B/C=D format
ary = str[1..-1].split("/").map { |i| i.split("=", 2) }
else
# Comma-separated
ary = str.split(",").map { |i| i.strip.split("=", 2) }
end
self.new(ary, template)
end
Parses the string representation of a distinguished name. Two different forms are supported:
OpenSSL format (X509_NAME_oneline()
) used by #to_s
. For example: /DC=com/DC=example/CN=nobody
OpenSSL format (X509_NAME_print()
) used by #to_s(OpenSSL::X509::Name::COMPAT)
. For example: DC=com, DC=example, CN=nobody
Neither of them is standardized and has quirks and inconsistencies in handling of escaped characters or multi-valued RDNs.
Use of this method is discouraged in new applications. See Name.parse_rfc2253
and to_utf8
for the alternative.
# File tmp/rubies/ruby-3.2.0/ext/openssl/lib/openssl/x509.rb, line 286
def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
self.new(ary, template)
end
Parses the UTF-8 string representation of a distinguished name, according to RFC 2253.
See also to_utf8
for the opposite operation.
static
VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self)
{
X509_NAME *name;
VALUE oid, value, type, opts, kwargs[2];
static ID kwargs_ids[2];
const char *oid_name;
int loc = -1, set = 0;
if (!kwargs_ids[0]) {
kwargs_ids[0] = rb_intern_const("loc");
kwargs_ids[1] = rb_intern_const("set");
}
rb_scan_args(argc, argv, "21:", &oid, &value, &type, &opts);
rb_get_kwargs(opts, kwargs_ids, 0, 2, kwargs);
oid_name = StringValueCStr(oid);
StringValue(value);
if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid);
if (kwargs[0] != Qundef)
loc = NUM2INT(kwargs[0]);
if (kwargs[1] != Qundef)
set = NUM2INT(kwargs[1]);
GetX509Name(self, name);
if (!X509_NAME_add_entry_by_txt(name, oid_name, NUM2INT(type),
(unsigned char *)RSTRING_PTR(value),
RSTRING_LENINT(value), loc, set))
ossl_raise(eX509NameError, "X509_NAME_add_entry_by_txt");
return self;
}
Adds a new entry with the given oid and value to this name. The oid is an object identifier defined in ASN.1. Some common OIDs are:
Country Name
Common Name
Domain Component
Organization Name
Organizational Unit Name
State or Province Name
The optional keyword parameters loc and set specify where to insert the new attribute. Refer to the manpage of X509_NAME_add_entry(3) for details. loc defaults to -1 and set defaults to 0. This appends a single-valued RDN to the end.
static VALUE
ossl_x509name_cmp(VALUE self, VALUE other)
{
int result;
if (!rb_obj_is_kind_of(other, cX509Name))
return Qnil;
result = ossl_x509name_cmp0(self, other);
if (result < 0) return INT2FIX(-1);
if (result > 0) return INT2FIX(1);
return INT2FIX(0);
}
Compares this Name
with other and returns 0
if they are the same and -1
or +1
if they are greater or less than each other respectively. Returns nil
if they are not comparable (i.e. different types).
static VALUE
ossl_x509name_eql(VALUE self, VALUE other)
{
if (!rb_obj_is_kind_of(other, cX509Name))
return Qfalse;
return ossl_x509name_cmp0(self, other) == 0 ? Qtrue : Qfalse;
}
Returns true if name and other refer to the same hash key.
static VALUE
ossl_x509name_hash(VALUE self)
{
X509_NAME *name;
unsigned long hash;
GetX509Name(self, name);
hash = X509_NAME_hash(name);
return ULONG2NUM(hash);
}
The hash value returned is suitable for use as a certificate’s filename in a CA path.
static VALUE
ossl_x509name_hash_old(VALUE self)
{
X509_NAME *name;
unsigned long hash;
GetX509Name(self, name);
hash = X509_NAME_hash_old(name);
return ULONG2NUM(hash);
}
Returns an MD5 based hash used in OpenSSL
0.9.X.
static VALUE
ossl_x509name_initialize_copy(VALUE self, VALUE other)
{
X509_NAME *name, *name_other, *name_new;
rb_check_frozen(self);
GetX509Name(self, name);
GetX509Name(other, name_other);
name_new = X509_NAME_dup(name_other);
if (!name_new)
ossl_raise(eX509NameError, "X509_NAME_dup");
SetX509Name(self, name_new);
X509_NAME_free(name);
return self;
}
# File tmp/rubies/ruby-3.2.0/ext/openssl/lib/openssl/x509.rb, line 319
def pretty_print(q)
q.object_group(self) {
q.text ' '
q.text to_s(OpenSSL::X509::Name::RFC2253)
}
end
static VALUE
ossl_x509name_to_a(VALUE self)
{
X509_NAME *name;
X509_NAME_ENTRY *entry;
int i,entries,nid;
char long_name[512];
const char *short_name;
VALUE ary, vname, ret;
ASN1_STRING *value;
GetX509Name(self, name);
entries = X509_NAME_entry_count(name);
if (entries < 0) {
OSSL_Debug("name entries < 0!");
return rb_ary_new();
}
ret = rb_ary_new2(entries);
for (i=0; i<entries; i++) {
if (!(entry = X509_NAME_get_entry(name, i))) {
ossl_raise(eX509NameError, NULL);
}
if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name),
X509_NAME_ENTRY_get_object(entry))) {
ossl_raise(eX509NameError, NULL);
}
nid = OBJ_ln2nid(long_name);
if (nid == NID_undef) {
vname = rb_str_new2((const char *) &long_name);
} else {
short_name = OBJ_nid2sn(nid);
vname = rb_str_new2(short_name); /*do not free*/
}
value = X509_NAME_ENTRY_get_data(entry);
ary = rb_ary_new3(3, vname, asn1str_to_str(value), INT2NUM(value->type));
rb_ary_push(ret, ary);
}
return ret;
}
static VALUE
ossl_x509name_to_der(VALUE self)
{
X509_NAME *name;
VALUE str;
long len;
unsigned char *p;
GetX509Name(self, name);
if((len = i2d_X509_NAME(name, NULL)) <= 0)
ossl_raise(eX509NameError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_X509_NAME(name, &p) <= 0)
ossl_raise(eX509NameError, NULL);
ossl_str_adjust(str, p);
return str;
}
Converts the name to DER encoding
static VALUE
ossl_x509name_to_s(int argc, VALUE *argv, VALUE self)
{
rb_check_arity(argc, 0, 1);
/* name.to_s(nil) was allowed */
if (!argc || NIL_P(argv[0]))
return ossl_x509name_to_s_old(self);
else
return x509name_print(self, NUM2ULONG(argv[0]));
}
Returns a String
representation of the Distinguished Name
. format is one of:
If format is omitted, the largely broken and traditional OpenSSL
format (X509_NAME_oneline()
format) is chosen.
Use of this method is discouraged. None of the formats other than OpenSSL::X509::Name::RFC2253
is standardized and may show an inconsistent behavior through OpenSSL versions.
It is recommended to use to_utf8
instead, which is equivalent to calling name.to_s(OpenSSL::X509::Name::RFC2253).force_encoding("UTF-8")
.
static VALUE
ossl_x509name_to_utf8(VALUE self)
{
VALUE str = x509name_print(self, XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
rb_enc_associate_index(str, rb_utf8_encindex());
return str;
}
Returns an UTF-8 representation of the distinguished name, as specified in RFC 2253.