openssl 2.2.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +33 -45
- data/History.md +260 -0
- data/ext/openssl/extconf.rb +85 -72
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +26 -45
- data/ext/openssl/ossl.c +67 -47
- data/ext/openssl/ossl.h +26 -6
- data/ext/openssl/ossl_asn1.c +26 -13
- data/ext/openssl/ossl_bn.c +278 -142
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +12 -13
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +15 -11
- data/ext/openssl/ossl_engine.c +16 -15
- data/ext/openssl/ossl_hmac.c +56 -135
- data/ext/openssl/ossl_kdf.c +11 -3
- data/ext/openssl/ossl_ocsp.c +5 -53
- data/ext/openssl/ossl_pkcs12.c +21 -3
- data/ext/openssl/ossl_pkcs7.c +42 -59
- data/ext/openssl/ossl_pkey.c +1142 -191
- data/ext/openssl/ossl_pkey.h +36 -73
- data/ext/openssl/ossl_pkey_dh.c +130 -340
- data/ext/openssl/ossl_pkey_dsa.c +100 -405
- data/ext/openssl/ossl_pkey_ec.c +163 -335
- data/ext/openssl/ossl_pkey_rsa.c +106 -493
- data/ext/openssl/ossl_ssl.c +529 -421
- data/ext/openssl/ossl_ssl_session.c +28 -29
- data/ext/openssl/ossl_ts.c +64 -39
- data/ext/openssl/ossl_x509.c +0 -6
- data/ext/openssl/ossl_x509cert.c +167 -11
- data/ext/openssl/ossl_x509crl.c +13 -10
- data/ext/openssl/ossl_x509ext.c +1 -2
- data/ext/openssl/ossl_x509name.c +9 -2
- data/ext/openssl/ossl_x509req.c +13 -10
- data/ext/openssl/ossl_x509revoked.c +3 -3
- data/ext/openssl/ossl_x509store.c +193 -90
- data/lib/openssl/buffering.rb +10 -1
- data/lib/openssl/hmac.rb +65 -0
- data/lib/openssl/pkey.rb +429 -0
- data/lib/openssl/ssl.rb +13 -8
- data/lib/openssl/version.rb +1 -1
- data/lib/openssl/x509.rb +22 -0
- data/lib/openssl.rb +0 -1
- metadata +8 -66
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -501
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
#include "ossl.h"
|
6
6
|
|
7
|
+
#ifndef OPENSSL_NO_SOCK
|
7
8
|
VALUE cSSLSession;
|
8
9
|
static VALUE eSSLSession;
|
9
10
|
|
@@ -34,43 +35,38 @@ static VALUE ossl_ssl_session_alloc(VALUE klass)
|
|
34
35
|
* Creates a new Session object from an instance of SSLSocket or DER/PEM encoded
|
35
36
|
* String.
|
36
37
|
*/
|
37
|
-
static VALUE
|
38
|
+
static VALUE
|
39
|
+
ossl_ssl_session_initialize(VALUE self, VALUE arg1)
|
38
40
|
{
|
39
|
-
|
40
|
-
|
41
|
-
if (RDATA(self)->data)
|
42
|
-
ossl_raise(eSSLSession, "SSL Session already initialized");
|
43
|
-
|
44
|
-
if (rb_obj_is_instance_of(arg1, cSSLSocket)) {
|
45
|
-
SSL *ssl;
|
46
|
-
|
47
|
-
GetSSL(arg1, ssl);
|
48
|
-
|
49
|
-
if ((ctx = SSL_get1_session(ssl)) == NULL)
|
50
|
-
ossl_raise(eSSLSession, "no session available");
|
51
|
-
} else {
|
52
|
-
BIO *in = ossl_obj2bio(&arg1);
|
41
|
+
SSL_SESSION *ctx;
|
53
42
|
|
54
|
-
|
43
|
+
if (RTYPEDDATA_DATA(self))
|
44
|
+
ossl_raise(eSSLSession, "SSL Session already initialized");
|
55
45
|
|
56
|
-
|
57
|
-
|
58
|
-
ctx = d2i_SSL_SESSION_bio(in, NULL);
|
59
|
-
}
|
46
|
+
if (rb_obj_is_instance_of(arg1, cSSLSocket)) {
|
47
|
+
SSL *ssl;
|
60
48
|
|
61
|
-
|
49
|
+
GetSSL(arg1, ssl);
|
62
50
|
|
63
|
-
|
64
|
-
|
65
|
-
|
51
|
+
if ((ctx = SSL_get1_session(ssl)) == NULL)
|
52
|
+
ossl_raise(eSSLSession, "no session available");
|
53
|
+
}
|
54
|
+
else {
|
55
|
+
BIO *in = ossl_obj2bio(&arg1);
|
66
56
|
|
67
|
-
|
68
|
-
|
69
|
-
|
57
|
+
ctx = d2i_SSL_SESSION_bio(in, NULL);
|
58
|
+
if (!ctx) {
|
59
|
+
OSSL_BIO_reset(in);
|
60
|
+
ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
|
61
|
+
}
|
62
|
+
BIO_free(in);
|
63
|
+
if (!ctx)
|
64
|
+
ossl_raise(rb_eArgError, "unknown type");
|
65
|
+
}
|
70
66
|
|
71
|
-
|
67
|
+
RTYPEDDATA_DATA(self) = ctx;
|
72
68
|
|
73
|
-
|
69
|
+
return self;
|
74
70
|
}
|
75
71
|
|
76
72
|
static VALUE
|
@@ -304,6 +300,7 @@ static VALUE ossl_ssl_session_to_text(VALUE self)
|
|
304
300
|
return ossl_membio2str(out);
|
305
301
|
}
|
306
302
|
|
303
|
+
#endif /* !defined(OPENSSL_NO_SOCK) */
|
307
304
|
|
308
305
|
void Init_ossl_ssl_session(void)
|
309
306
|
{
|
@@ -312,6 +309,7 @@ void Init_ossl_ssl_session(void)
|
|
312
309
|
mSSL = rb_define_module_under(mOSSL, "SSL");
|
313
310
|
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
314
311
|
#endif
|
312
|
+
#ifndef OPENSSL_NO_SOCK
|
315
313
|
cSSLSession = rb_define_class_under(mSSL, "Session", rb_cObject);
|
316
314
|
eSSLSession = rb_define_class_under(cSSLSession, "SessionError", eOSSLError);
|
317
315
|
|
@@ -329,4 +327,5 @@ void Init_ossl_ssl_session(void)
|
|
329
327
|
rb_define_method(cSSLSession, "to_der", ossl_ssl_session_to_der, 0);
|
330
328
|
rb_define_method(cSSLSession, "to_pem", ossl_ssl_session_to_pem, 0);
|
331
329
|
rb_define_method(cSSLSession, "to_text", ossl_ssl_session_to_text, 0);
|
330
|
+
#endif /* !defined(OPENSSL_NO_SOCK) */
|
332
331
|
}
|
data/ext/openssl/ossl_ts.c
CHANGED
@@ -68,9 +68,9 @@ static VALUE cTimestampRequest;
|
|
68
68
|
static VALUE cTimestampResponse;
|
69
69
|
static VALUE cTimestampTokenInfo;
|
70
70
|
static VALUE cTimestampFactory;
|
71
|
-
static
|
72
|
-
static
|
73
|
-
static
|
71
|
+
static VALUE sBAD_ALG, sBAD_REQUEST, sBAD_DATA_FORMAT, sTIME_NOT_AVAILABLE;
|
72
|
+
static VALUE sUNACCEPTED_POLICY, sUNACCEPTED_EXTENSION, sADD_INFO_NOT_AVAILABLE;
|
73
|
+
static VALUE sSYSTEM_FAILURE;
|
74
74
|
|
75
75
|
static void
|
76
76
|
ossl_ts_req_free(void *ptr)
|
@@ -145,6 +145,12 @@ obj_to_asn1obj(VALUE obj)
|
|
145
145
|
return a1obj;
|
146
146
|
}
|
147
147
|
|
148
|
+
static VALUE
|
149
|
+
obj_to_asn1obj_i(VALUE obj)
|
150
|
+
{
|
151
|
+
return (VALUE)obj_to_asn1obj(obj);
|
152
|
+
}
|
153
|
+
|
148
154
|
static VALUE
|
149
155
|
get_asn1obj(ASN1_OBJECT *obj)
|
150
156
|
{
|
@@ -205,8 +211,10 @@ ossl_ts_req_initialize(int argc, VALUE *argv, VALUE self)
|
|
205
211
|
in = ossl_obj2bio(&arg);
|
206
212
|
ts_req = d2i_TS_REQ_bio(in, &ts_req);
|
207
213
|
BIO_free(in);
|
208
|
-
if (!ts_req)
|
214
|
+
if (!ts_req) {
|
215
|
+
DATA_PTR(self) = NULL;
|
209
216
|
ossl_raise(eTimestampError, "Error when decoding the timestamp request");
|
217
|
+
}
|
210
218
|
DATA_PTR(self) = ts_req;
|
211
219
|
|
212
220
|
return self;
|
@@ -529,8 +537,10 @@ ossl_ts_resp_initialize(VALUE self, VALUE der)
|
|
529
537
|
in = ossl_obj2bio(&der);
|
530
538
|
ts_resp = d2i_TS_RESP_bio(in, &ts_resp);
|
531
539
|
BIO_free(in);
|
532
|
-
if (!ts_resp)
|
540
|
+
if (!ts_resp) {
|
541
|
+
DATA_PTR(self) = NULL;
|
533
542
|
ossl_raise(eTimestampError, "Error when decoding the timestamp response");
|
543
|
+
}
|
534
544
|
DATA_PTR(self) = ts_resp;
|
535
545
|
|
536
546
|
return self;
|
@@ -816,17 +826,14 @@ ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self)
|
|
816
826
|
X509_up_ref(cert);
|
817
827
|
}
|
818
828
|
|
819
|
-
|
829
|
+
TS_VERIFY_CTX_set_certs(ctx, x509inter);
|
820
830
|
TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE);
|
821
831
|
TS_VERIFY_CTX_set_store(ctx, x509st);
|
822
832
|
|
823
833
|
ok = TS_RESP_verify_response(ctx, resp);
|
824
|
-
|
825
|
-
|
826
|
-
*
|
827
|
-
* this. To prevent our X509_STORE from being freed with our
|
828
|
-
* TS_VERIFY_CTX we set the store to NULL first.
|
829
|
-
* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2)
|
834
|
+
/*
|
835
|
+
* TS_VERIFY_CTX_set_store() call above does not increment the reference
|
836
|
+
* counter, so it must be unset before TS_VERIFY_CTX_free() is called.
|
830
837
|
*/
|
831
838
|
TS_VERIFY_CTX_set_store(ctx, NULL);
|
832
839
|
TS_VERIFY_CTX_free(ctx);
|
@@ -871,8 +878,10 @@ ossl_ts_token_info_initialize(VALUE self, VALUE der)
|
|
871
878
|
in = ossl_obj2bio(&der);
|
872
879
|
info = d2i_TS_TST_INFO_bio(in, &info);
|
873
880
|
BIO_free(in);
|
874
|
-
if (!info)
|
881
|
+
if (!info) {
|
882
|
+
DATA_PTR(self) = NULL;
|
875
883
|
ossl_raise(eTimestampError, "Error when decoding the timestamp token info");
|
884
|
+
}
|
876
885
|
DATA_PTR(self) = info;
|
877
886
|
|
878
887
|
return self;
|
@@ -1074,13 +1083,29 @@ ossl_tsfac_serial_cb(struct TS_resp_ctx *ctx, void *data)
|
|
1074
1083
|
}
|
1075
1084
|
|
1076
1085
|
static int
|
1086
|
+
#if !defined(LIBRESSL_VERSION_NUMBER)
|
1077
1087
|
ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, long *sec, long *usec)
|
1088
|
+
#else
|
1089
|
+
ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec)
|
1090
|
+
#endif
|
1078
1091
|
{
|
1079
1092
|
*sec = *((long *)data);
|
1080
1093
|
*usec = 0;
|
1081
1094
|
return 1;
|
1082
1095
|
}
|
1083
1096
|
|
1097
|
+
static VALUE
|
1098
|
+
ossl_evp_get_digestbyname_i(VALUE arg)
|
1099
|
+
{
|
1100
|
+
return (VALUE)ossl_evp_get_digestbyname(arg);
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
static VALUE
|
1104
|
+
ossl_obj2bio_i(VALUE arg)
|
1105
|
+
{
|
1106
|
+
return (VALUE)ossl_obj2bio((VALUE *)arg);
|
1107
|
+
}
|
1108
|
+
|
1084
1109
|
/*
|
1085
1110
|
* Creates a Response with the help of an OpenSSL::PKey, an
|
1086
1111
|
* OpenSSL::X509::Certificate and a Request.
|
@@ -1149,7 +1174,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request)
|
|
1149
1174
|
goto end;
|
1150
1175
|
}
|
1151
1176
|
if (!NIL_P(def_policy_id) && !TS_REQ_get_policy_id(req)) {
|
1152
|
-
def_policy_id_obj = (ASN1_OBJECT*)rb_protect(
|
1177
|
+
def_policy_id_obj = (ASN1_OBJECT*)rb_protect(obj_to_asn1obj_i, (VALUE)def_policy_id, &status);
|
1153
1178
|
if (status)
|
1154
1179
|
goto end;
|
1155
1180
|
}
|
@@ -1191,7 +1216,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request)
|
|
1191
1216
|
|
1192
1217
|
for (i = 0; i < RARRAY_LEN(allowed_digests); i++) {
|
1193
1218
|
rbmd = rb_ary_entry(allowed_digests, i);
|
1194
|
-
md = (const EVP_MD *)rb_protect(
|
1219
|
+
md = (const EVP_MD *)rb_protect(ossl_evp_get_digestbyname_i, rbmd, &status);
|
1195
1220
|
if (status)
|
1196
1221
|
goto end;
|
1197
1222
|
TS_RESP_CTX_add_md(ctx, md);
|
@@ -1202,7 +1227,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request)
|
|
1202
1227
|
if (status)
|
1203
1228
|
goto end;
|
1204
1229
|
|
1205
|
-
req_bio = (BIO*)rb_protect(
|
1230
|
+
req_bio = (BIO*)rb_protect(ossl_obj2bio_i, (VALUE)&str, &status);
|
1206
1231
|
if (status)
|
1207
1232
|
goto end;
|
1208
1233
|
|
@@ -1226,7 +1251,7 @@ end:
|
|
1226
1251
|
ASN1_OBJECT_free(def_policy_id_obj);
|
1227
1252
|
TS_RESP_CTX_free(ctx);
|
1228
1253
|
if (err_msg)
|
1229
|
-
|
1254
|
+
rb_exc_raise(ossl_make_error(eTimestampError, rb_str_new_cstr(err_msg)));
|
1230
1255
|
if (status)
|
1231
1256
|
rb_jump_tag(status);
|
1232
1257
|
return ret;
|
@@ -1247,24 +1272,24 @@ Init_ossl_ts(void)
|
|
1247
1272
|
* timestamp server rejects the message imprint algorithm used in the
|
1248
1273
|
* +Request+
|
1249
1274
|
*/
|
1250
|
-
sBAD_ALG =
|
1275
|
+
sBAD_ALG = ID2SYM(rb_intern_const("BAD_ALG"));
|
1251
1276
|
|
1252
1277
|
/*
|
1253
1278
|
* Possible return value for +Response#failure_info+. Indicates that the
|
1254
1279
|
* timestamp server was not able to process the +Request+ properly.
|
1255
1280
|
*/
|
1256
|
-
sBAD_REQUEST =
|
1281
|
+
sBAD_REQUEST = ID2SYM(rb_intern_const("BAD_REQUEST"));
|
1257
1282
|
/*
|
1258
1283
|
* Possible return value for +Response#failure_info+. Indicates that the
|
1259
1284
|
* timestamp server was not able to parse certain data in the +Request+.
|
1260
1285
|
*/
|
1261
|
-
sBAD_DATA_FORMAT =
|
1286
|
+
sBAD_DATA_FORMAT = ID2SYM(rb_intern_const("BAD_DATA_FORMAT"));
|
1262
1287
|
|
1263
|
-
sTIME_NOT_AVAILABLE =
|
1264
|
-
sUNACCEPTED_POLICY =
|
1265
|
-
sUNACCEPTED_EXTENSION =
|
1266
|
-
sADD_INFO_NOT_AVAILABLE =
|
1267
|
-
sSYSTEM_FAILURE =
|
1288
|
+
sTIME_NOT_AVAILABLE = ID2SYM(rb_intern_const("TIME_NOT_AVAILABLE"));
|
1289
|
+
sUNACCEPTED_POLICY = ID2SYM(rb_intern_const("UNACCEPTED_POLICY"));
|
1290
|
+
sUNACCEPTED_EXTENSION = ID2SYM(rb_intern_const("UNACCEPTED_EXTENSION"));
|
1291
|
+
sADD_INFO_NOT_AVAILABLE = ID2SYM(rb_intern_const("ADD_INFO_NOT_AVAILABLE"));
|
1292
|
+
sSYSTEM_FAILURE = ID2SYM(rb_intern_const("SYSTEM_FAILURE"));
|
1268
1293
|
|
1269
1294
|
/* Document-class: OpenSSL::Timestamp
|
1270
1295
|
* Provides classes and methods to request, create and validate
|
@@ -1280,7 +1305,7 @@ Init_ossl_ts(void)
|
|
1280
1305
|
* ===Create a Response:
|
1281
1306
|
* #Assumes ts.p12 is a PKCS#12-compatible file with a private key
|
1282
1307
|
* #and a certificate that has an extended key usage of 'timeStamping'
|
1283
|
-
* p12 = OpenSSL::PKCS12.new(File.
|
1308
|
+
* p12 = OpenSSL::PKCS12.new(File.binread('ts.p12'), 'pwd')
|
1284
1309
|
* md = OpenSSL::Digest.new('SHA1')
|
1285
1310
|
* hash = md.digest(data) #some binary data to be timestamped
|
1286
1311
|
* req = OpenSSL::Timestamp::Request.new
|
@@ -1295,16 +1320,16 @@ Init_ossl_ts(void)
|
|
1295
1320
|
*
|
1296
1321
|
* ===Verify a timestamp response:
|
1297
1322
|
* #Assume we have a timestamp token in a file called ts.der
|
1298
|
-
* ts = OpenSSL::Timestamp::Response.new(File.
|
1323
|
+
* ts = OpenSSL::Timestamp::Response.new(File.binread('ts.der'))
|
1299
1324
|
* #Assume we have the Request for this token in a file called req.der
|
1300
|
-
* req = OpenSSL::Timestamp::Request.new(File.
|
1325
|
+
* req = OpenSSL::Timestamp::Request.new(File.binread('req.der'))
|
1301
1326
|
* # Assume the associated root CA certificate is contained in a
|
1302
1327
|
* # DER-encoded file named root.cer
|
1303
|
-
* root = OpenSSL::X509::Certificate.new(File.
|
1328
|
+
* root = OpenSSL::X509::Certificate.new(File.binread('root.cer'))
|
1304
1329
|
* # get the necessary intermediate certificates, available in
|
1305
1330
|
* # DER-encoded form in inter1.cer and inter2.cer
|
1306
|
-
* inter1 = OpenSSL::X509::Certificate.new(File.
|
1307
|
-
* inter2 = OpenSSL::X509::Certificate.new(File.
|
1331
|
+
* inter1 = OpenSSL::X509::Certificate.new(File.binread('inter1.cer'))
|
1332
|
+
* inter2 = OpenSSL::X509::Certificate.new(File.binread('inter2.cer'))
|
1308
1333
|
* ts.verify(req, root, inter1, inter2) -> ts or raises an exception if validation fails
|
1309
1334
|
*
|
1310
1335
|
*/
|
@@ -1437,9 +1462,9 @@ Init_ossl_ts(void)
|
|
1437
1462
|
* timestamping certificate.
|
1438
1463
|
*
|
1439
1464
|
* req = OpenSSL::Timestamp::Request.new(raw_bytes)
|
1440
|
-
* p12 = OpenSSL::PKCS12.new(File.
|
1441
|
-
* inter1 = OpenSSL::X509::Certificate.new(File.
|
1442
|
-
* inter2 = OpenSSL::X509::Certificate.new(File.
|
1465
|
+
* p12 = OpenSSL::PKCS12.new(File.binread('ts.p12'), 'pwd')
|
1466
|
+
* inter1 = OpenSSL::X509::Certificate.new(File.binread('inter1.cer'))
|
1467
|
+
* inter2 = OpenSSL::X509::Certificate.new(File.binread('inter2.cer'))
|
1443
1468
|
* fac = OpenSSL::Timestamp::Factory.new
|
1444
1469
|
* fac.gen_time = Time.now
|
1445
1470
|
* fac.serial_number = 1
|
@@ -1503,11 +1528,11 @@ Init_ossl_ts(void)
|
|
1503
1528
|
*
|
1504
1529
|
*/
|
1505
1530
|
cTimestampFactory = rb_define_class_under(mTimestamp, "Factory", rb_cObject);
|
1506
|
-
rb_attr(cTimestampFactory,
|
1507
|
-
rb_attr(cTimestampFactory,
|
1508
|
-
rb_attr(cTimestampFactory,
|
1509
|
-
rb_attr(cTimestampFactory,
|
1510
|
-
rb_attr(cTimestampFactory,
|
1531
|
+
rb_attr(cTimestampFactory, rb_intern_const("allowed_digests"), 1, 1, 0);
|
1532
|
+
rb_attr(cTimestampFactory, rb_intern_const("default_policy_id"), 1, 1, 0);
|
1533
|
+
rb_attr(cTimestampFactory, rb_intern_const("serial_number"), 1, 1, 0);
|
1534
|
+
rb_attr(cTimestampFactory, rb_intern_const("gen_time"), 1, 1, 0);
|
1535
|
+
rb_attr(cTimestampFactory, rb_intern_const("additional_certs"), 1, 1, 0);
|
1511
1536
|
rb_define_method(cTimestampFactory, "create_timestamp", ossl_tsfac_create_ts, 3);
|
1512
1537
|
}
|
1513
1538
|
|
data/ext/openssl/ossl_x509.c
CHANGED
@@ -115,11 +115,9 @@ Init_ossl_x509(void)
|
|
115
115
|
DefX509Const(V_ERR_SUITE_B_LOS_NOT_ALLOWED);
|
116
116
|
DefX509Const(V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256);
|
117
117
|
#endif
|
118
|
-
#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
|
119
118
|
DefX509Const(V_ERR_HOSTNAME_MISMATCH);
|
120
119
|
DefX509Const(V_ERR_EMAIL_MISMATCH);
|
121
120
|
DefX509Const(V_ERR_IP_ADDRESS_MISMATCH);
|
122
|
-
#endif
|
123
121
|
#if defined(X509_V_ERR_DANE_NO_MATCH)
|
124
122
|
DefX509Const(V_ERR_DANE_NO_MATCH);
|
125
123
|
#endif
|
@@ -187,12 +185,10 @@ Init_ossl_x509(void)
|
|
187
185
|
/* Set by Store#flags= and StoreContext#flags=. Enables checking of the
|
188
186
|
* signature of the root self-signed CA. */
|
189
187
|
DefX509Const(V_FLAG_CHECK_SS_SIGNATURE);
|
190
|
-
#if defined(X509_V_FLAG_TRUSTED_FIRST)
|
191
188
|
/* Set by Store#flags= and StoreContext#flags=. When constructing a
|
192
189
|
* certificate chain, search the Store first for the issuer certificate.
|
193
190
|
* Enabled by default in OpenSSL >= 1.1.0. */
|
194
191
|
DefX509Const(V_FLAG_TRUSTED_FIRST);
|
195
|
-
#endif
|
196
192
|
#if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY)
|
197
193
|
/* Set by Store#flags= and StoreContext#flags=.
|
198
194
|
* Enables Suite B 128 bit only mode. */
|
@@ -208,11 +204,9 @@ Init_ossl_x509(void)
|
|
208
204
|
* Enables Suite B 128 bit mode allowing 192 bit algorithms. */
|
209
205
|
DefX509Const(V_FLAG_SUITEB_128_LOS);
|
210
206
|
#endif
|
211
|
-
#if defined(X509_V_FLAG_PARTIAL_CHAIN)
|
212
207
|
/* Set by Store#flags= and StoreContext#flags=.
|
213
208
|
* Allows partial chains if at least one certificate is in trusted store. */
|
214
209
|
DefX509Const(V_FLAG_PARTIAL_CHAIN);
|
215
|
-
#endif
|
216
210
|
#if defined(X509_V_FLAG_NO_ALT_CHAINS)
|
217
211
|
/* Set by Store#flags= and StoreContext#flags=. Suppresses searching for
|
218
212
|
* a alternative chain. No effect in OpenSSL >= 1.1.0. */
|
data/ext/openssl/ossl_x509cert.c
CHANGED
@@ -115,24 +115,27 @@ static VALUE
|
|
115
115
|
ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
|
116
116
|
{
|
117
117
|
BIO *in;
|
118
|
-
X509 *x509, *
|
118
|
+
X509 *x509, *x509_orig = RTYPEDDATA_DATA(self);
|
119
119
|
VALUE arg;
|
120
120
|
|
121
|
+
rb_check_frozen(self);
|
121
122
|
if (rb_scan_args(argc, argv, "01", &arg) == 0) {
|
122
123
|
/* create just empty X509Cert */
|
123
124
|
return self;
|
124
125
|
}
|
125
126
|
arg = ossl_to_der_if_possible(arg);
|
126
127
|
in = ossl_obj2bio(&arg);
|
127
|
-
x509 =
|
128
|
-
DATA_PTR(self) = x;
|
128
|
+
x509 = d2i_X509_bio(in, NULL);
|
129
129
|
if (!x509) {
|
130
|
-
|
131
|
-
|
132
|
-
DATA_PTR(self) = x;
|
130
|
+
OSSL_BIO_reset(in);
|
131
|
+
x509 = PEM_read_bio_X509(in, NULL, NULL, NULL);
|
133
132
|
}
|
134
133
|
BIO_free(in);
|
135
|
-
if (!x509)
|
134
|
+
if (!x509)
|
135
|
+
ossl_raise(eX509CertError, "PEM_read_bio_X509");
|
136
|
+
|
137
|
+
RTYPEDDATA_DATA(self) = x509;
|
138
|
+
X509_free(x509_orig);
|
136
139
|
|
137
140
|
return self;
|
138
141
|
}
|
@@ -639,12 +642,12 @@ ossl_x509_set_extensions(VALUE self, VALUE ary)
|
|
639
642
|
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
|
640
643
|
}
|
641
644
|
GetX509(self, x509);
|
642
|
-
|
643
|
-
|
645
|
+
for (i = X509_get_ext_count(x509); i > 0; i--)
|
646
|
+
X509_EXTENSION_free(X509_delete_ext(x509, 0));
|
644
647
|
for (i=0; i<RARRAY_LEN(ary); i++) {
|
645
648
|
ext = GetX509ExtPtr(RARRAY_AREF(ary, i));
|
646
649
|
if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */
|
647
|
-
ossl_raise(eX509CertError,
|
650
|
+
ossl_raise(eX509CertError, "X509_add_ext");
|
648
651
|
}
|
649
652
|
}
|
650
653
|
|
@@ -704,6 +707,157 @@ ossl_x509_eq(VALUE self, VALUE other)
|
|
704
707
|
return !X509_cmp(a, b) ? Qtrue : Qfalse;
|
705
708
|
}
|
706
709
|
|
710
|
+
struct load_chained_certificates_arguments {
|
711
|
+
VALUE certificates;
|
712
|
+
X509 *certificate;
|
713
|
+
};
|
714
|
+
|
715
|
+
static VALUE
|
716
|
+
load_chained_certificates_append_push(VALUE _arguments) {
|
717
|
+
struct load_chained_certificates_arguments *arguments = (struct load_chained_certificates_arguments*)_arguments;
|
718
|
+
|
719
|
+
if (arguments->certificates == Qnil) {
|
720
|
+
arguments->certificates = rb_ary_new();
|
721
|
+
}
|
722
|
+
|
723
|
+
rb_ary_push(arguments->certificates, ossl_x509_new(arguments->certificate));
|
724
|
+
|
725
|
+
return Qnil;
|
726
|
+
}
|
727
|
+
|
728
|
+
static VALUE
|
729
|
+
load_chained_certificate_append_ensure(VALUE _arguments) {
|
730
|
+
struct load_chained_certificates_arguments *arguments = (struct load_chained_certificates_arguments*)_arguments;
|
731
|
+
|
732
|
+
X509_free(arguments->certificate);
|
733
|
+
|
734
|
+
return Qnil;
|
735
|
+
}
|
736
|
+
|
737
|
+
inline static VALUE
|
738
|
+
load_chained_certificates_append(VALUE certificates, X509 *certificate) {
|
739
|
+
struct load_chained_certificates_arguments arguments;
|
740
|
+
arguments.certificates = certificates;
|
741
|
+
arguments.certificate = certificate;
|
742
|
+
|
743
|
+
rb_ensure(load_chained_certificates_append_push, (VALUE)&arguments, load_chained_certificate_append_ensure, (VALUE)&arguments);
|
744
|
+
|
745
|
+
return arguments.certificates;
|
746
|
+
}
|
747
|
+
|
748
|
+
static VALUE
|
749
|
+
load_chained_certificates_PEM(BIO *in) {
|
750
|
+
VALUE certificates = Qnil;
|
751
|
+
X509 *certificate = PEM_read_bio_X509(in, NULL, NULL, NULL);
|
752
|
+
|
753
|
+
/* If we cannot read even one certificate: */
|
754
|
+
if (certificate == NULL) {
|
755
|
+
/* If we cannot read one certificate because we could not read the PEM encoding: */
|
756
|
+
if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) {
|
757
|
+
ossl_clear_error();
|
758
|
+
}
|
759
|
+
|
760
|
+
if (ERR_peek_last_error())
|
761
|
+
ossl_raise(eX509CertError, NULL);
|
762
|
+
else
|
763
|
+
return Qnil;
|
764
|
+
}
|
765
|
+
|
766
|
+
certificates = load_chained_certificates_append(Qnil, certificate);
|
767
|
+
|
768
|
+
while ((certificate = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
|
769
|
+
load_chained_certificates_append(certificates, certificate);
|
770
|
+
}
|
771
|
+
|
772
|
+
/* We tried to read one more certificate but could not read start line: */
|
773
|
+
if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) {
|
774
|
+
/* This is not an error, it means we are finished: */
|
775
|
+
ossl_clear_error();
|
776
|
+
|
777
|
+
return certificates;
|
778
|
+
}
|
779
|
+
|
780
|
+
/* Alternatively, if we reached the end of the file and there was no error: */
|
781
|
+
if (BIO_eof(in) && !ERR_peek_last_error()) {
|
782
|
+
return certificates;
|
783
|
+
} else {
|
784
|
+
/* Otherwise, we tried to read a certificate but failed somewhere: */
|
785
|
+
ossl_raise(eX509CertError, NULL);
|
786
|
+
}
|
787
|
+
}
|
788
|
+
|
789
|
+
static VALUE
|
790
|
+
load_chained_certificates_DER(BIO *in) {
|
791
|
+
X509 *certificate = d2i_X509_bio(in, NULL);
|
792
|
+
|
793
|
+
/* If we cannot read one certificate: */
|
794
|
+
if (certificate == NULL) {
|
795
|
+
/* Ignore error. We could not load. */
|
796
|
+
ossl_clear_error();
|
797
|
+
|
798
|
+
return Qnil;
|
799
|
+
}
|
800
|
+
|
801
|
+
return load_chained_certificates_append(Qnil, certificate);
|
802
|
+
}
|
803
|
+
|
804
|
+
static VALUE
|
805
|
+
load_chained_certificates(VALUE _io) {
|
806
|
+
BIO *in = (BIO*)_io;
|
807
|
+
VALUE certificates = Qnil;
|
808
|
+
|
809
|
+
/*
|
810
|
+
DER is a binary format and it may contain octets within it that look like
|
811
|
+
PEM encoded certificates. So we need to check DER first.
|
812
|
+
*/
|
813
|
+
certificates = load_chained_certificates_DER(in);
|
814
|
+
|
815
|
+
if (certificates != Qnil)
|
816
|
+
return certificates;
|
817
|
+
|
818
|
+
OSSL_BIO_reset(in);
|
819
|
+
|
820
|
+
certificates = load_chained_certificates_PEM(in);
|
821
|
+
|
822
|
+
if (certificates != Qnil)
|
823
|
+
return certificates;
|
824
|
+
|
825
|
+
/* Otherwise we couldn't read the output correctly so fail: */
|
826
|
+
ossl_raise(eX509CertError, "Could not detect format of certificate data!");
|
827
|
+
}
|
828
|
+
|
829
|
+
static VALUE
|
830
|
+
load_chained_certificates_ensure(VALUE _io) {
|
831
|
+
BIO *in = (BIO*)_io;
|
832
|
+
|
833
|
+
BIO_free(in);
|
834
|
+
|
835
|
+
return Qnil;
|
836
|
+
}
|
837
|
+
|
838
|
+
/*
|
839
|
+
* call-seq:
|
840
|
+
* OpenSSL::X509::Certificate.load(string) -> [certs...]
|
841
|
+
* OpenSSL::X509::Certificate.load(file) -> [certs...]
|
842
|
+
*
|
843
|
+
* Read the chained certificates from the given input. Supports both PEM
|
844
|
+
* and DER encoded certificates.
|
845
|
+
*
|
846
|
+
* PEM is a text format and supports more than one certificate.
|
847
|
+
*
|
848
|
+
* DER is a binary format and only supports one certificate.
|
849
|
+
*
|
850
|
+
* If the file is empty, or contains only unrelated data, an
|
851
|
+
* +OpenSSL::X509::CertificateError+ exception will be raised.
|
852
|
+
*/
|
853
|
+
static VALUE
|
854
|
+
ossl_x509_load(VALUE klass, VALUE buffer)
|
855
|
+
{
|
856
|
+
BIO *in = ossl_obj2bio(&buffer);
|
857
|
+
|
858
|
+
return rb_ensure(load_chained_certificates, (VALUE)in, load_chained_certificates_ensure, (VALUE)in);
|
859
|
+
}
|
860
|
+
|
707
861
|
/*
|
708
862
|
* INIT
|
709
863
|
*/
|
@@ -730,7 +884,7 @@ Init_ossl_x509cert(void)
|
|
730
884
|
* Certificate is capable of handling DER-encoded certificates and
|
731
885
|
* certificates encoded in OpenSSL's PEM format.
|
732
886
|
*
|
733
|
-
* raw = File.
|
887
|
+
* raw = File.binread "cert.cer" # DER- or PEM-encoded
|
734
888
|
* certificate = OpenSSL::X509::Certificate.new raw
|
735
889
|
*
|
736
890
|
* === Saving a certificate to a file
|
@@ -812,6 +966,8 @@ Init_ossl_x509cert(void)
|
|
812
966
|
*/
|
813
967
|
cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
|
814
968
|
|
969
|
+
rb_define_singleton_method(cX509Cert, "load", ossl_x509_load, 1);
|
970
|
+
|
815
971
|
rb_define_alloc_func(cX509Cert, ossl_x509_alloc);
|
816
972
|
rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1);
|
817
973
|
rb_define_method(cX509Cert, "initialize_copy", ossl_x509_copy, 1);
|
data/ext/openssl/ossl_x509crl.c
CHANGED
@@ -93,23 +93,26 @@ static VALUE
|
|
93
93
|
ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
|
94
94
|
{
|
95
95
|
BIO *in;
|
96
|
-
X509_CRL *crl, *
|
96
|
+
X509_CRL *crl, *crl_orig = RTYPEDDATA_DATA(self);
|
97
97
|
VALUE arg;
|
98
98
|
|
99
|
+
rb_check_frozen(self);
|
99
100
|
if (rb_scan_args(argc, argv, "01", &arg) == 0) {
|
100
101
|
return self;
|
101
102
|
}
|
102
103
|
arg = ossl_to_der_if_possible(arg);
|
103
104
|
in = ossl_obj2bio(&arg);
|
104
|
-
crl =
|
105
|
-
DATA_PTR(self) = x;
|
105
|
+
crl = d2i_X509_CRL_bio(in, NULL);
|
106
106
|
if (!crl) {
|
107
|
-
|
108
|
-
|
109
|
-
DATA_PTR(self) = x;
|
107
|
+
OSSL_BIO_reset(in);
|
108
|
+
crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
|
110
109
|
}
|
111
110
|
BIO_free(in);
|
112
|
-
if (!crl)
|
111
|
+
if (!crl)
|
112
|
+
ossl_raise(eX509CRLError, "PEM_read_bio_X509_CRL");
|
113
|
+
|
114
|
+
RTYPEDDATA_DATA(self) = crl;
|
115
|
+
X509_CRL_free(crl_orig);
|
113
116
|
|
114
117
|
return self;
|
115
118
|
}
|
@@ -471,12 +474,12 @@ ossl_x509crl_set_extensions(VALUE self, VALUE ary)
|
|
471
474
|
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
|
472
475
|
}
|
473
476
|
GetX509CRL(self, crl);
|
474
|
-
|
475
|
-
|
477
|
+
for (i = X509_CRL_get_ext_count(crl); i > 0; i--)
|
478
|
+
X509_EXTENSION_free(X509_CRL_delete_ext(crl, 0));
|
476
479
|
for (i=0; i<RARRAY_LEN(ary); i++) {
|
477
480
|
ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); /* NO NEED TO DUP */
|
478
481
|
if (!X509_CRL_add_ext(crl, ext, -1)) {
|
479
|
-
ossl_raise(eX509CRLError,
|
482
|
+
ossl_raise(eX509CRLError, "X509_CRL_add_ext");
|
480
483
|
}
|
481
484
|
}
|
482
485
|
|
data/ext/openssl/ossl_x509ext.c
CHANGED
@@ -226,11 +226,10 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
|
|
226
226
|
GetX509ExtFactory(self, ctx);
|
227
227
|
obj = NewX509Ext(cX509Ext);
|
228
228
|
rconf = rb_iv_get(self, "@config");
|
229
|
-
conf = NIL_P(rconf) ? NULL :
|
229
|
+
conf = NIL_P(rconf) ? NULL : GetConfig(rconf);
|
230
230
|
X509V3_set_nconf(ctx, conf);
|
231
231
|
ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
|
232
232
|
X509V3_set_ctx_nodb(ctx);
|
233
|
-
NCONF_free(conf);
|
234
233
|
if (!ext){
|
235
234
|
ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr);
|
236
235
|
}
|