Skip to content

Commit 7b1668e

Browse files
authored
Merge pull request #967 from rhenium/ky/asn1-refactor-obj-str-convert
asn1: refactor converting ASN1_OBJECT to string
2 parents 9203380 + 2ea36c2 commit 7b1668e

File tree

15 files changed

+152
-182
lines changed

15 files changed

+152
-182
lines changed

ext/openssl/ossl_asn1.c

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,48 @@ asn1integer_to_num_i(VALUE arg)
147147
return asn1integer_to_num((ASN1_INTEGER *)arg);
148148
}
149149

150+
/*
151+
* ASN1_OBJECT conversions
152+
*/
153+
VALUE
154+
ossl_asn1obj_to_string_oid(const ASN1_OBJECT *a1obj)
155+
{
156+
VALUE str;
157+
int len;
158+
159+
str = rb_usascii_str_new(NULL, 127);
160+
len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1);
161+
if (len <= 0 || len == INT_MAX)
162+
ossl_raise(eOSSLError, "OBJ_obj2txt");
163+
if (len > RSTRING_LEN(str)) {
164+
/* +1 is for the \0 terminator added by OBJ_obj2txt() */
165+
rb_str_resize(str, len + 1);
166+
len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1);
167+
if (len <= 0)
168+
ossl_raise(eOSSLError, "OBJ_obj2txt");
169+
}
170+
rb_str_set_len(str, len);
171+
return str;
172+
}
173+
174+
VALUE
175+
ossl_asn1obj_to_string(const ASN1_OBJECT *obj)
176+
{
177+
int nid = OBJ_obj2nid(obj);
178+
if (nid != NID_undef)
179+
return rb_str_new_cstr(OBJ_nid2sn(nid));
180+
return ossl_asn1obj_to_string_oid(obj);
181+
}
182+
183+
VALUE
184+
ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *obj)
185+
{
186+
int nid = OBJ_obj2nid(obj);
187+
if (nid != NID_undef)
188+
return rb_str_new_cstr(OBJ_nid2ln(nid));
189+
return ossl_asn1obj_to_string_oid(obj);
190+
}
191+
150192
/********/
151193
/*
152194
* ASN1 module
@@ -160,7 +202,7 @@ asn1integer_to_num_i(VALUE arg)
160202
#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v))
161203

162204
VALUE mASN1;
163-
VALUE eASN1Error;
205+
static VALUE eASN1Error;
164206

165207
VALUE cASN1Data;
166208
static VALUE cASN1Primitive;
@@ -247,8 +289,8 @@ obj_to_asn1null(VALUE obj)
247289
return null;
248290
}
249291

250-
static ASN1_OBJECT*
251-
obj_to_asn1obj(VALUE obj)
292+
ASN1_OBJECT *
293+
ossl_to_asn1obj(VALUE obj)
252294
{
253295
ASN1_OBJECT *a1obj;
254296

@@ -393,32 +435,27 @@ decode_null(unsigned char* der, long length)
393435
return Qnil;
394436
}
395437

438+
VALUE
439+
asn1obj_to_string_i(VALUE arg)
440+
{
441+
return ossl_asn1obj_to_string((const ASN1_OBJECT *)arg);
442+
}
443+
396444
static VALUE
397445
decode_obj(unsigned char* der, long length)
398446
{
399447
ASN1_OBJECT *obj;
400448
const unsigned char *p;
401449
VALUE ret;
402-
int nid;
403-
BIO *bio;
450+
int state;
404451

405452
p = der;
406-
if(!(obj = d2i_ASN1_OBJECT(NULL, &p, length)))
407-
ossl_raise(eASN1Error, NULL);
408-
if((nid = OBJ_obj2nid(obj)) != NID_undef){
409-
ASN1_OBJECT_free(obj);
410-
ret = rb_str_new2(OBJ_nid2sn(nid));
411-
}
412-
else{
413-
if(!(bio = BIO_new(BIO_s_mem()))){
414-
ASN1_OBJECT_free(obj);
415-
ossl_raise(eASN1Error, NULL);
416-
}
417-
i2a_ASN1_OBJECT(bio, obj);
418-
ASN1_OBJECT_free(obj);
419-
ret = ossl_membio2str(bio);
420-
}
421-
453+
if (!(obj = d2i_ASN1_OBJECT(NULL, &p, length)))
454+
ossl_raise(eASN1Error, "d2i_ASN1_OBJECT");
455+
ret = rb_protect(asn1obj_to_string_i, (VALUE)obj, &state);
456+
ASN1_OBJECT_free(obj);
457+
if (state)
458+
rb_jump_tag(state);
422459
return ret;
423460
}
424461

@@ -544,7 +581,7 @@ ossl_asn1_get_asn1type(VALUE obj)
544581
free_func = (free_func_type *)ASN1_STRING_free;
545582
break;
546583
case V_ASN1_OBJECT:
547-
ptr = obj_to_asn1obj(value);
584+
ptr = ossl_to_asn1obj(value);
548585
free_func = (free_func_type *)ASN1_OBJECT_free;
549586
break;
550587
case V_ASN1_UTCTIME:
@@ -1172,23 +1209,7 @@ ossl_asn1obj_get_ln(VALUE self)
11721209
static VALUE
11731210
asn1obj_get_oid_i(VALUE vobj)
11741211
{
1175-
ASN1_OBJECT *a1obj = (void *)vobj;
1176-
VALUE str;
1177-
int len;
1178-
1179-
str = rb_usascii_str_new(NULL, 127);
1180-
len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1);
1181-
if (len <= 0 || len == INT_MAX)
1182-
ossl_raise(eASN1Error, "OBJ_obj2txt");
1183-
if (len > RSTRING_LEN(str)) {
1184-
/* +1 is for the \0 terminator added by OBJ_obj2txt() */
1185-
rb_str_resize(str, len + 1);
1186-
len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1);
1187-
if (len <= 0)
1188-
ossl_raise(eASN1Error, "OBJ_obj2txt");
1189-
}
1190-
rb_str_set_len(str, len);
1191-
return str;
1212+
return ossl_asn1obj_to_string_oid((const ASN1_OBJECT *)vobj);
11921213
}
11931214

11941215
/*
@@ -1205,7 +1226,7 @@ ossl_asn1obj_get_oid(VALUE self)
12051226
ASN1_OBJECT *a1obj;
12061227
int state;
12071228

1208-
a1obj = obj_to_asn1obj(ossl_asn1_get_value(self));
1229+
a1obj = ossl_to_asn1obj(ossl_asn1_get_value(self));
12091230
str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state);
12101231
ASN1_OBJECT_free(a1obj);
12111232
if (state)

ext/openssl/ossl_asn1.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,25 @@ VALUE asn1str_to_str(const ASN1_STRING *);
3131
VALUE asn1integer_to_num(const ASN1_INTEGER *);
3232
ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *);
3333

34+
/*
35+
* ASN1_OBJECT conversions
36+
*/
37+
ASN1_OBJECT *ossl_to_asn1obj(VALUE obj);
38+
/*
39+
* Returns the short name if available, the dotted decimal notation otherwise.
40+
* This is the most common way to return ASN1_OBJECT to Ruby.
41+
*/
42+
VALUE ossl_asn1obj_to_string(const ASN1_OBJECT *a1obj);
43+
/*
44+
* However, some places use long names instead. This is likely unintentional,
45+
* but we keep the current behavior in existing methods.
46+
*/
47+
VALUE ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *a1obj);
48+
3449
/*
3550
* ASN1 module
3651
*/
3752
extern VALUE mASN1;
38-
extern VALUE eASN1Error;
3953

4054
extern VALUE cASN1Data;
4155

ext/openssl/ossl_ocsp.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,19 +1591,10 @@ ossl_ocspcid_get_hash_algorithm(VALUE self)
15911591
{
15921592
OCSP_CERTID *id;
15931593
ASN1_OBJECT *oid;
1594-
BIO *out;
15951594

15961595
GetOCSPCertId(self, id);
15971596
OCSP_id_get0_info(NULL, &oid, NULL, NULL, id);
1598-
1599-
if (!(out = BIO_new(BIO_s_mem())))
1600-
ossl_raise(eOCSPError, "BIO_new");
1601-
1602-
if (!i2a_ASN1_OBJECT(out, oid)) {
1603-
BIO_free(out);
1604-
ossl_raise(eOCSPError, "i2a_ASN1_OBJECT");
1605-
}
1606-
return ossl_membio2str(out);
1597+
return ossl_asn1obj_to_string_long_name(oid);
16071598
}
16081599

16091600
/*

ext/openssl/ossl_ts.c

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -132,44 +132,10 @@ asn1_to_der(void *template, int (*i2d)(void *template, unsigned char **pp))
132132
return str;
133133
}
134134

135-
static ASN1_OBJECT*
136-
obj_to_asn1obj(VALUE obj)
137-
{
138-
ASN1_OBJECT *a1obj;
139-
140-
StringValue(obj);
141-
a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 0);
142-
if(!a1obj) a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 1);
143-
if(!a1obj) ossl_raise(eASN1Error, "invalid OBJECT ID");
144-
145-
return a1obj;
146-
}
147-
148135
static VALUE
149136
obj_to_asn1obj_i(VALUE obj)
150137
{
151-
return (VALUE)obj_to_asn1obj(obj);
152-
}
153-
154-
static VALUE
155-
get_asn1obj(const ASN1_OBJECT *obj)
156-
{
157-
BIO *out;
158-
VALUE ret;
159-
int nid;
160-
if ((nid = OBJ_obj2nid(obj)) != NID_undef)
161-
ret = rb_str_new2(OBJ_nid2sn(nid));
162-
else{
163-
if (!(out = BIO_new(BIO_s_mem())))
164-
ossl_raise(eTimestampError, "BIO_new(BIO_s_mem())");
165-
if (i2a_ASN1_OBJECT(out, obj) <= 0) {
166-
BIO_free(out);
167-
ossl_raise(eTimestampError, "i2a_ASN1_OBJECT");
168-
}
169-
ret = ossl_membio2str(out);
170-
}
171-
172-
return ret;
138+
return (VALUE)ossl_to_asn1obj(obj);
173139
}
174140

175141
static VALUE
@@ -242,7 +208,7 @@ ossl_ts_req_get_algorithm(VALUE self)
242208
mi = TS_REQ_get_msg_imprint(req);
243209
algor = TS_MSG_IMPRINT_get_algo(mi);
244210
X509_ALGOR_get0(&obj, NULL, NULL, algor);
245-
return get_asn1obj(obj);
211+
return ossl_asn1obj_to_string(obj);
246212
}
247213

248214
/*
@@ -264,7 +230,7 @@ ossl_ts_req_set_algorithm(VALUE self, VALUE algo)
264230
X509_ALGOR *algor;
265231

266232
GetTSRequest(self, req);
267-
obj = obj_to_asn1obj(algo);
233+
obj = ossl_to_asn1obj(algo);
268234
mi = TS_REQ_get_msg_imprint(req);
269235
algor = TS_MSG_IMPRINT_get_algo(mi);
270236
if (!X509_ALGOR_set0(algor, obj, V_ASN1_NULL, NULL)) {
@@ -371,7 +337,7 @@ ossl_ts_req_get_policy_id(VALUE self)
371337
GetTSRequest(self, req);
372338
if (!TS_REQ_get_policy_id(req))
373339
return Qnil;
374-
return get_asn1obj(TS_REQ_get_policy_id(req));
340+
return ossl_asn1obj_to_string(TS_REQ_get_policy_id(req));
375341
}
376342

377343
/*
@@ -394,7 +360,7 @@ ossl_ts_req_set_policy_id(VALUE self, VALUE oid)
394360
int ok;
395361

396362
GetTSRequest(self, req);
397-
obj = obj_to_asn1obj(oid);
363+
obj = ossl_to_asn1obj(oid);
398364
ok = TS_REQ_set_policy_id(req, obj);
399365
ASN1_OBJECT_free(obj);
400366
if (!ok)
@@ -961,7 +927,7 @@ ossl_ts_token_info_get_policy_id(VALUE self)
961927
TS_TST_INFO *info;
962928

963929
GetTSTokenInfo(self, info);
964-
return get_asn1obj(TS_TST_INFO_get_policy_id(info));
930+
return ossl_asn1obj_to_string(TS_TST_INFO_get_policy_id(info));
965931
}
966932

967933
/*
@@ -989,7 +955,7 @@ ossl_ts_token_info_get_algorithm(VALUE self)
989955
mi = TS_TST_INFO_get_msg_imprint(info);
990956
algo = TS_MSG_IMPRINT_get_algo(mi);
991957
X509_ALGOR_get0(&obj, NULL, NULL, algo);
992-
return get_asn1obj(obj);
958+
return ossl_asn1obj_to_string(obj);
993959
}
994960

995961
/*

ext/openssl/ossl_x509attr.c

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -164,29 +164,18 @@ ossl_x509attr_set_oid(VALUE self, VALUE oid)
164164

165165
/*
166166
* call-seq:
167-
* attr.oid => string
167+
* attr.oid -> string
168+
*
169+
* Returns the OID of the attribute. Returns the short name or the dotted
170+
* decimal notation.
168171
*/
169172
static VALUE
170173
ossl_x509attr_get_oid(VALUE self)
171174
{
172175
X509_ATTRIBUTE *attr;
173-
ASN1_OBJECT *oid;
174-
BIO *out;
175-
VALUE ret;
176-
int nid;
177176

178177
GetX509Attr(self, attr);
179-
oid = X509_ATTRIBUTE_get0_object(attr);
180-
if ((nid = OBJ_obj2nid(oid)) != NID_undef)
181-
ret = rb_str_new2(OBJ_nid2sn(nid));
182-
else{
183-
if (!(out = BIO_new(BIO_s_mem())))
184-
ossl_raise(eX509AttrError, NULL);
185-
i2a_ASN1_OBJECT(out, oid);
186-
ret = ossl_membio2str(out);
187-
}
188-
189-
return ret;
178+
return ossl_asn1obj_to_string(X509_ATTRIBUTE_get0_object(attr));
190179
}
191180

192181
/*

ext/openssl/ossl_x509cert.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -318,27 +318,23 @@ ossl_x509_set_serial(VALUE self, VALUE num)
318318
/*
319319
* call-seq:
320320
* cert.signature_algorithm => string
321+
*
322+
* Returns the signature algorithm used to sign this certificate. This returns
323+
* the algorithm name found in the TBSCertificate structure, not the outer
324+
* \Certificate structure.
325+
*
326+
* Returns the long name of the signature algorithm, or the dotted decimal
327+
* notation if \OpenSSL does not define a long name for it.
321328
*/
322329
static VALUE
323330
ossl_x509_get_signature_algorithm(VALUE self)
324331
{
325332
X509 *x509;
326-
BIO *out;
327333
const ASN1_OBJECT *obj;
328-
VALUE str;
329334

330335
GetX509(self, x509);
331-
out = BIO_new(BIO_s_mem());
332-
if (!out) ossl_raise(eX509CertError, NULL);
333-
334336
X509_ALGOR_get0(&obj, NULL, NULL, X509_get0_tbs_sigalg(x509));
335-
if (!i2a_ASN1_OBJECT(out, obj)) {
336-
BIO_free(out);
337-
ossl_raise(eX509CertError, NULL);
338-
}
339-
str = ossl_membio2str(out);
340-
341-
return str;
337+
return ossl_asn1obj_to_string_long_name(obj);
342338
}
343339

344340
/*

0 commit comments

Comments
 (0)