openssl 2.2.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +33 -45
- data/History.md +300 -0
- data/README.md +36 -19
- data/ext/openssl/extconf.rb +119 -79
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +26 -45
- data/ext/openssl/ossl.c +131 -233
- data/ext/openssl/ossl.h +31 -12
- data/ext/openssl/ossl_asn1.c +26 -13
- data/ext/openssl/ossl_bn.c +279 -143
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +13 -14
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +16 -12
- data/ext/openssl/ossl_engine.c +17 -16
- data/ext/openssl/ossl_hmac.c +57 -136
- data/ext/openssl/ossl_kdf.c +12 -4
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +11 -59
- data/ext/openssl/ossl_pkcs12.c +22 -4
- data/ext/openssl/ossl_pkcs7.c +45 -62
- data/ext/openssl/ossl_pkey.c +1320 -196
- data/ext/openssl/ossl_pkey.h +36 -73
- data/ext/openssl/ossl_pkey_dh.c +152 -347
- data/ext/openssl/ossl_pkey_dsa.c +157 -413
- data/ext/openssl/ossl_pkey_ec.c +227 -343
- data/ext/openssl/ossl_pkey_rsa.c +159 -491
- data/ext/openssl/ossl_provider.c +211 -0
- data/ext/openssl/ossl_provider.h +5 -0
- data/ext/openssl/ossl_ssl.c +593 -467
- data/ext/openssl/ossl_ssl_session.c +29 -30
- data/ext/openssl/ossl_ts.c +67 -42
- data/ext/openssl/ossl_x509.c +0 -6
- data/ext/openssl/ossl_x509attr.c +1 -1
- data/ext/openssl/ossl_x509cert.c +168 -12
- data/ext/openssl/ossl_x509crl.c +14 -11
- data/ext/openssl/ossl_x509ext.c +14 -9
- data/ext/openssl/ossl_x509name.c +10 -3
- data/ext/openssl/ossl_x509req.c +14 -11
- data/ext/openssl/ossl_x509revoked.c +4 -4
- data/ext/openssl/ossl_x509store.c +204 -94
- data/lib/openssl/buffering.rb +10 -4
- data/lib/openssl/digest.rb +1 -5
- data/lib/openssl/hmac.rb +65 -0
- data/lib/openssl/pkey.rb +429 -0
- data/lib/openssl/ssl.rb +23 -18
- data/lib/openssl/version.rb +1 -1
- data/lib/openssl/x509.rb +22 -0
- data/lib/openssl.rb +0 -1
- metadata +13 -68
- 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
|
|
@@ -18,7 +19,7 @@ const rb_data_type_t ossl_ssl_session_type = {
|
|
18
19
|
{
|
19
20
|
0, ossl_ssl_session_free,
|
20
21
|
},
|
21
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
22
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
22
23
|
};
|
23
24
|
|
24
25
|
static VALUE ossl_ssl_session_alloc(VALUE klass)
|
@@ -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)
|
@@ -83,7 +83,7 @@ static const rb_data_type_t ossl_ts_req_type = {
|
|
83
83
|
{
|
84
84
|
0, ossl_ts_req_free,
|
85
85
|
},
|
86
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
86
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
87
87
|
};
|
88
88
|
|
89
89
|
static void
|
@@ -97,7 +97,7 @@ static const rb_data_type_t ossl_ts_resp_type = {
|
|
97
97
|
{
|
98
98
|
0, ossl_ts_resp_free,
|
99
99
|
},
|
100
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
100
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
101
101
|
};
|
102
102
|
|
103
103
|
static void
|
@@ -111,7 +111,7 @@ static const rb_data_type_t ossl_ts_token_info_type = {
|
|
111
111
|
{
|
112
112
|
0, ossl_ts_token_info_free,
|
113
113
|
},
|
114
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
114
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
115
115
|
};
|
116
116
|
|
117
117
|
static VALUE
|
@@ -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_x509attr.c
CHANGED
data/ext/openssl/ossl_x509cert.c
CHANGED
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509_type = {
|
|
41
41
|
{
|
42
42
|
0, ossl_x509_free,
|
43
43
|
},
|
44
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
44
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
45
45
|
};
|
46
46
|
|
47
47
|
/*
|
@@ -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);
|