Skip to content

Commit 9092c27

Browse files
committed
Merge branch 'maint-3.2'
* maint-3.2: test_provider.rb: Make a legacy provider test optional. .github/workflows/test.yml: synchronize with master pkcs7: fix memory leak in error path of PKCS7.new and .read_smime asn1: fix ObjectId#== x509: fix handling of multiple URIs in Certificate#crl_uris test_x509cert.rb: break up test_extension into smaller units
2 parents bd647c3 + 1f07615 commit 9092c27

File tree

5 files changed

+126
-51
lines changed

5 files changed

+126
-51
lines changed

ext/openssl/ossl_asn1.c

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,30 +1167,6 @@ ossl_asn1obj_get_ln(VALUE self)
11671167
return ret;
11681168
}
11691169

1170-
/*
1171-
* call-seq:
1172-
* oid == other_oid => true or false
1173-
*
1174-
* Returns +true+ if _other_oid_ is the same as _oid_
1175-
*/
1176-
static VALUE
1177-
ossl_asn1obj_eq(VALUE self, VALUE other)
1178-
{
1179-
VALUE valSelf, valOther;
1180-
int nidSelf, nidOther;
1181-
1182-
valSelf = ossl_asn1_get_value(self);
1183-
valOther = ossl_asn1_get_value(other);
1184-
1185-
if ((nidSelf = OBJ_txt2nid(StringValueCStr(valSelf))) == NID_undef)
1186-
ossl_raise(eASN1Error, "OBJ_txt2nid");
1187-
1188-
if ((nidOther = OBJ_txt2nid(StringValueCStr(valOther))) == NID_undef)
1189-
ossl_raise(eASN1Error, "OBJ_txt2nid");
1190-
1191-
return nidSelf == nidOther ? Qtrue : Qfalse;
1192-
}
1193-
11941170
static VALUE
11951171
asn1obj_get_oid_i(VALUE vobj)
11961172
{
@@ -1235,6 +1211,25 @@ ossl_asn1obj_get_oid(VALUE self)
12351211
return str;
12361212
}
12371213

1214+
/*
1215+
* call-seq:
1216+
* oid == other_oid => true or false
1217+
*
1218+
* Returns +true+ if _other_oid_ is the same as _oid_.
1219+
*/
1220+
static VALUE
1221+
ossl_asn1obj_eq(VALUE self, VALUE other)
1222+
{
1223+
VALUE oid1, oid2;
1224+
1225+
if (!rb_obj_is_kind_of(other, cASN1ObjectId))
1226+
return Qfalse;
1227+
1228+
oid1 = ossl_asn1obj_get_oid(self);
1229+
oid2 = ossl_asn1obj_get_oid(other);
1230+
return rb_str_equal(oid1, oid2);
1231+
}
1232+
12381233
#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
12391234
static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
12401235
{ return rb_funcallv_public(cASN1##klass, rb_intern("new"), argc, argv); }

ext/openssl/ossl_pkcs7.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,10 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg)
167167
BIO_free(in);
168168
if (!pkcs7)
169169
ossl_raise(ePKCS7Error, "Could not parse the PKCS7");
170-
if (!pkcs7->d.ptr)
170+
if (!pkcs7->d.ptr) {
171+
PKCS7_free(pkcs7);
171172
ossl_raise(ePKCS7Error, "No content in PKCS7");
173+
}
172174

173175
data = out ? ossl_membio2str(out) : Qnil;
174176
SetPKCS7(ret, pkcs7);
@@ -348,8 +350,10 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
348350
BIO_free(in);
349351
if (!p7)
350352
ossl_raise(rb_eArgError, "Could not parse the PKCS7");
351-
if (!p7->d.ptr)
353+
if (!p7->d.ptr) {
354+
PKCS7_free(p7);
352355
ossl_raise(rb_eArgError, "No content in PKCS7");
356+
}
353357

354358
RTYPEDDATA_DATA(self) = p7;
355359
PKCS7_free(p7_orig);

lib/openssl/x509.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ module CRLDistributionPoints
122122
include Helpers
123123

124124
# Get the distributionPoint fullName URI from the certificate's CRL
125-
# distribution points extension, as described in RFC5280 Section
126-
# 4.2.1.13
125+
# distribution points extension, as described in RFC 5280 Section
126+
# 4.2.1.13.
127127
#
128128
# Returns an array of strings or nil or raises ASN1::ASN1Error.
129129
def crl_uris
@@ -135,19 +135,19 @@ def crl_uris
135135
raise ASN1::ASN1Error, "invalid extension"
136136
end
137137

138-
crl_uris = cdp_asn1.map do |crl_distribution_point|
138+
crl_uris = cdp_asn1.flat_map do |crl_distribution_point|
139139
distribution_point = crl_distribution_point.value.find do |v|
140140
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
141141
end
142142
full_name = distribution_point&.value&.find do |v|
143143
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
144144
end
145-
full_name&.value&.find do |v|
145+
full_name&.value&.select do |v|
146146
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 6 # uniformResourceIdentifier
147147
end
148148
end
149149

150-
crl_uris&.map(&:value)
150+
crl_uris.empty? ? nil : crl_uris.map(&:value)
151151
end
152152
end
153153

test/openssl/test_asn1.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,9 @@ def test_object_identifier
326326
oid = (0...100).to_a.join(".").b
327327
obj = OpenSSL::ASN1::ObjectId.new(oid)
328328
assert_equal oid, obj.oid
329+
end
329330

331+
def test_object_identifier_equality
330332
aki = [
331333
OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier"),
332334
OpenSSL::ASN1::ObjectId.new("X509v3 Authority Key Identifier"),
@@ -341,17 +343,22 @@ def test_object_identifier
341343

342344
aki.each do |a|
343345
aki.each do |b|
344-
assert a == b
346+
assert_equal true, a == b
345347
end
346348

347349
ski.each do |b|
348-
refute a == b
350+
assert_equal false, a == b
349351
end
350352
end
351353

352-
assert_raise(TypeError) {
353-
OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier") == nil
354-
}
354+
obj1 = OpenSSL::ASN1::ObjectId.new("1.2.34.56789.10")
355+
obj2 = OpenSSL::ASN1::ObjectId.new("1.2.34.56789.10")
356+
obj3 = OpenSSL::ASN1::ObjectId.new("1.2.34.56789.11")
357+
omit "OID 1.2.34.56789.10 is registered" if obj1.sn
358+
assert_equal true, obj1 == obj2
359+
assert_equal false, obj1 == obj3
360+
361+
assert_equal false, OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier") == nil
355362
end
356363

357364
def test_sequence

test/openssl/test_x509cert.rb

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,14 @@ def test_validity
6868
assert_equal(now.getutc, cert.not_after)
6969
end
7070

71-
def test_extension
71+
def test_extension_factory
7272
ca_exts = [
7373
["basicConstraints","CA:TRUE",true],
7474
["keyUsage","keyCertSign, cRLSign",true],
7575
["subjectKeyIdentifier","hash",false],
7676
["authorityKeyIdentifier","issuer:always,keyid:always",false],
7777
]
7878
ca_cert = issue_cert(@ca, @rsa2048, 1, ca_exts, nil, nil)
79-
keyid = get_subject_key_id(ca_cert.to_der, hex: false)
80-
assert_equal keyid, ca_cert.authority_key_identifier
81-
assert_equal keyid, ca_cert.subject_key_identifier
8279
ca_cert.extensions.each_with_index{|ext, i|
8380
assert_equal(ca_exts[i].first, ext.oid)
8481
assert_equal(ca_exts[i].last, ext.critical?)
@@ -90,33 +87,112 @@ def test_extension
9087
["authorityKeyIdentifier","issuer:always,keyid:always",false],
9188
["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
9289
["subjectAltName","email:ee1@ruby-lang.org",false],
93-
["authorityInfoAccess","caIssuers;URI:http://www.example.com/caIssuers,OCSP;URI:http://www.example.com/ocsp",false],
9490
]
9591
ee1_cert = issue_cert(@ee1, @rsa1024, 2, ee1_exts, ca_cert, @rsa2048)
9692
assert_equal(ca_cert.subject.to_der, ee1_cert.issuer.to_der)
9793
ee1_cert.extensions.each_with_index{|ext, i|
9894
assert_equal(ee1_exts[i].first, ext.oid)
9995
assert_equal(ee1_exts[i].last, ext.critical?)
10096
}
101-
assert_nil(ee1_cert.crl_uris)
97+
end
98+
99+
def test_akiski
100+
ca_cert = generate_cert(@ca, @rsa2048, 4, nil)
101+
ef = OpenSSL::X509::ExtensionFactory.new(ca_cert, ca_cert)
102+
ca_cert.add_extension(
103+
ef.create_extension("subjectKeyIdentifier", "hash", false))
104+
ca_cert.add_extension(
105+
ef.create_extension("authorityKeyIdentifier", "issuer:always,keyid:always", false))
106+
ca_cert.sign(@rsa2048, "sha256")
107+
108+
ca_keyid = get_subject_key_id(ca_cert.to_der, hex: false)
109+
assert_equal ca_keyid, ca_cert.authority_key_identifier
110+
assert_equal ca_keyid, ca_cert.subject_key_identifier
111+
112+
ee_cert = generate_cert(@ee1, Fixtures.pkey("p256"), 5, ca_cert)
113+
ef = OpenSSL::X509::ExtensionFactory.new(ca_cert, ee_cert)
114+
ee_cert.add_extension(
115+
ef.create_extension("subjectKeyIdentifier", "hash", false))
116+
ee_cert.add_extension(
117+
ef.create_extension("authorityKeyIdentifier", "issuer:always,keyid:always", false))
118+
ee_cert.sign(@rsa2048, "sha256")
119+
120+
ee_keyid = get_subject_key_id(ee_cert.to_der, hex: false)
121+
assert_equal ca_keyid, ee_cert.authority_key_identifier
122+
assert_equal ee_keyid, ee_cert.subject_key_identifier
123+
end
124+
125+
def test_akiski_missing
126+
cert = issue_cert(@ee1, @rsa2048, 1, [], nil, nil)
127+
assert_nil(cert.authority_key_identifier)
128+
assert_nil(cert.subject_key_identifier)
129+
end
130+
131+
def test_crl_uris_no_crl_distribution_points
132+
cert = issue_cert(@ee1, @rsa2048, 1, [], nil, nil)
133+
assert_nil(cert.crl_uris)
134+
end
102135

136+
def test_crl_uris
137+
# Multiple DistributionPoint contains a single general name each
103138
ef = OpenSSL::X509::ExtensionFactory.new
104139
ef.config = OpenSSL::Config.parse(<<~_cnf_)
105140
[crlDistPts]
106141
URI.1 = http://www.example.com/crl
107142
URI.2 = ldap://ldap.example.com/cn=ca?certificateRevocationList;binary
108143
_cnf_
109-
cdp_cert = generate_cert(@ee1, @rsa1024, 3, ca_cert)
144+
cdp_cert = generate_cert(@ee1, @rsa2048, 3, nil)
110145
ef.subject_certificate = cdp_cert
111146
cdp_cert.add_extension(ef.create_extension("crlDistributionPoints", "@crlDistPts"))
112147
cdp_cert.sign(@rsa2048, "sha256")
113148
assert_equal(
114149
["http://www.example.com/crl", "ldap://ldap.example.com/cn=ca?certificateRevocationList;binary"],
115150
cdp_cert.crl_uris
116151
)
152+
end
117153

154+
def test_crl_uris_multiple_general_names
155+
# Single DistributionPoint contains multiple general names of type URI
118156
ef = OpenSSL::X509::ExtensionFactory.new
119-
aia_cert = generate_cert(@ee1, @rsa1024, 4, ca_cert)
157+
ef.config = OpenSSL::Config.parse(<<~_cnf_)
158+
[crlDistPts_section]
159+
fullname = URI:http://www.example.com/crl, URI:ldap://ldap.example.com/cn=ca?certificateRevocationList;binary
160+
_cnf_
161+
cdp_cert = generate_cert(@ee1, @rsa2048, 3, nil)
162+
ef.subject_certificate = cdp_cert
163+
cdp_cert.add_extension(ef.create_extension("crlDistributionPoints", "crlDistPts_section"))
164+
cdp_cert.sign(@rsa2048, "sha256")
165+
assert_equal(
166+
["http://www.example.com/crl", "ldap://ldap.example.com/cn=ca?certificateRevocationList;binary"],
167+
cdp_cert.crl_uris
168+
)
169+
end
170+
171+
def test_crl_uris_no_uris
172+
# The only DistributionPointName is a directoryName
173+
ef = OpenSSL::X509::ExtensionFactory.new
174+
ef.config = OpenSSL::Config.parse(<<~_cnf_)
175+
[crlDistPts_section]
176+
fullname = dirName:dirname_section
177+
[dirname_section]
178+
CN = dirname
179+
_cnf_
180+
cdp_cert = generate_cert(@ee1, @rsa2048, 3, nil)
181+
ef.subject_certificate = cdp_cert
182+
cdp_cert.add_extension(ef.create_extension("crlDistributionPoints", "crlDistPts_section"))
183+
cdp_cert.sign(@rsa2048, "sha256")
184+
assert_nil(cdp_cert.crl_uris)
185+
end
186+
187+
def test_aia_missing
188+
cert = issue_cert(@ee1, @rsa2048, 1, [], nil, nil)
189+
assert_nil(cert.ca_issuer_uris)
190+
assert_nil(cert.ocsp_uris)
191+
end
192+
193+
def test_aia
194+
ef = OpenSSL::X509::ExtensionFactory.new
195+
aia_cert = generate_cert(@ee1, @rsa2048, 4, nil)
120196
ef.subject_certificate = aia_cert
121197
aia_cert.add_extension(
122198
ef.create_extension(
@@ -137,13 +213,6 @@ def test_extension
137213
["http://www.example.com/ocsp", "ldap://ldap.example.com/cn=ca?authorityInfoAccessOcsp;binary"],
138214
aia_cert.ocsp_uris
139215
)
140-
141-
no_exts_cert = issue_cert(@ca, @rsa2048, 5, [], nil, nil)
142-
assert_equal nil, no_exts_cert.authority_key_identifier
143-
assert_equal nil, no_exts_cert.subject_key_identifier
144-
assert_equal nil, no_exts_cert.crl_uris
145-
assert_equal nil, no_exts_cert.ca_issuer_uris
146-
assert_equal nil, no_exts_cert.ocsp_uris
147216
end
148217

149218
def test_invalid_extension

0 commit comments

Comments
 (0)