openssl 2.2.0 → 3.0.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 +32 -44
- data/History.md +155 -0
- data/ext/openssl/extconf.rb +43 -38
- 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 +20 -6
- data/ext/openssl/ossl_asn1.c +16 -4
- data/ext/openssl/ossl_bn.c +267 -143
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +11 -11
- 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 +48 -135
- data/ext/openssl/ossl_kdf.c +8 -0
- data/ext/openssl/ossl_ocsp.c +3 -51
- data/ext/openssl/ossl_pkcs12.c +21 -3
- data/ext/openssl/ossl_pkcs7.c +42 -59
- data/ext/openssl/ossl_pkey.c +1102 -191
- data/ext/openssl/ossl_pkey.h +35 -72
- data/ext/openssl/ossl_pkey_dh.c +124 -334
- data/ext/openssl/ossl_pkey_dsa.c +93 -398
- data/ext/openssl/ossl_pkey_ec.c +126 -318
- data/ext/openssl/ossl_pkey_rsa.c +100 -487
- data/ext/openssl/ossl_ssl.c +322 -375
- data/ext/openssl/ossl_ssl_session.c +24 -29
- data/ext/openssl/ossl_ts.c +64 -39
- data/ext/openssl/ossl_x509.c +0 -6
- data/ext/openssl/ossl_x509cert.c +164 -8
- data/ext/openssl/ossl_x509crl.c +10 -7
- data/ext/openssl/ossl_x509ext.c +1 -2
- data/ext/openssl/ossl_x509name.c +9 -2
- data/ext/openssl/ossl_x509req.c +10 -7
- 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 +417 -0
- data/lib/openssl/ssl.rb +8 -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
@@ -34,43 +34,38 @@ static VALUE ossl_ssl_session_alloc(VALUE klass)
|
|
34
34
|
* Creates a new Session object from an instance of SSLSocket or DER/PEM encoded
|
35
35
|
* String.
|
36
36
|
*/
|
37
|
-
static VALUE
|
37
|
+
static VALUE
|
38
|
+
ossl_ssl_session_initialize(VALUE self, VALUE arg1)
|
38
39
|
{
|
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);
|
40
|
+
SSL_SESSION *ctx;
|
53
41
|
|
54
|
-
|
42
|
+
if (RTYPEDDATA_DATA(self))
|
43
|
+
ossl_raise(eSSLSession, "SSL Session already initialized");
|
55
44
|
|
56
|
-
|
57
|
-
|
58
|
-
ctx = d2i_SSL_SESSION_bio(in, NULL);
|
59
|
-
}
|
45
|
+
if (rb_obj_is_instance_of(arg1, cSSLSocket)) {
|
46
|
+
SSL *ssl;
|
60
47
|
|
61
|
-
|
48
|
+
GetSSL(arg1, ssl);
|
62
49
|
|
63
|
-
|
64
|
-
|
65
|
-
|
50
|
+
if ((ctx = SSL_get1_session(ssl)) == NULL)
|
51
|
+
ossl_raise(eSSLSession, "no session available");
|
52
|
+
}
|
53
|
+
else {
|
54
|
+
BIO *in = ossl_obj2bio(&arg1);
|
66
55
|
|
67
|
-
|
68
|
-
|
69
|
-
|
56
|
+
ctx = d2i_SSL_SESSION_bio(in, NULL);
|
57
|
+
if (!ctx) {
|
58
|
+
OSSL_BIO_reset(in);
|
59
|
+
ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
|
60
|
+
}
|
61
|
+
BIO_free(in);
|
62
|
+
if (!ctx)
|
63
|
+
ossl_raise(rb_eArgError, "unknown type");
|
64
|
+
}
|
70
65
|
|
71
|
-
|
66
|
+
RTYPEDDATA_DATA(self) = ctx;
|
72
67
|
|
73
|
-
|
68
|
+
return self;
|
74
69
|
}
|
75
70
|
|
76
71
|
static VALUE
|
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
|
}
|
@@ -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
|
}
|
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
|
}
|
data/ext/openssl/ossl_x509name.c
CHANGED
@@ -291,7 +291,14 @@ x509name_print(VALUE self, unsigned long iflag)
|
|
291
291
|
* * OpenSSL::X509::Name::MULTILINE
|
292
292
|
*
|
293
293
|
* If _format_ is omitted, the largely broken and traditional OpenSSL format
|
294
|
-
* is
|
294
|
+
* (<tt>X509_NAME_oneline()</tt> format) is chosen.
|
295
|
+
*
|
296
|
+
* <b>Use of this method is discouraged.</b> None of the formats other than
|
297
|
+
* OpenSSL::X509::Name::RFC2253 is standardized and may show an inconsistent
|
298
|
+
* behavior through \OpenSSL versions.
|
299
|
+
*
|
300
|
+
* It is recommended to use #to_utf8 instead, which is equivalent to calling
|
301
|
+
* <tt>name.to_s(OpenSSL::X509::Name::RFC2253).force_encoding("UTF-8")</tt>.
|
295
302
|
*/
|
296
303
|
static VALUE
|
297
304
|
ossl_x509name_to_s(int argc, VALUE *argv, VALUE self)
|
@@ -498,7 +505,7 @@ ossl_x509name_to_der(VALUE self)
|
|
498
505
|
* You can create a Name by parsing a distinguished name String or by
|
499
506
|
* supplying the distinguished name as an Array.
|
500
507
|
*
|
501
|
-
* name = OpenSSL::X509::Name.
|
508
|
+
* name = OpenSSL::X509::Name.parse_rfc2253 'DC=example,CN=nobody'
|
502
509
|
*
|
503
510
|
* name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]
|
504
511
|
*/
|
data/ext/openssl/ossl_x509req.c
CHANGED
@@ -79,23 +79,26 @@ static VALUE
|
|
79
79
|
ossl_x509req_initialize(int argc, VALUE *argv, VALUE self)
|
80
80
|
{
|
81
81
|
BIO *in;
|
82
|
-
X509_REQ *req, *
|
82
|
+
X509_REQ *req, *req_orig = RTYPEDDATA_DATA(self);
|
83
83
|
VALUE arg;
|
84
84
|
|
85
|
+
rb_check_frozen(self);
|
85
86
|
if (rb_scan_args(argc, argv, "01", &arg) == 0) {
|
86
87
|
return self;
|
87
88
|
}
|
88
89
|
arg = ossl_to_der_if_possible(arg);
|
89
90
|
in = ossl_obj2bio(&arg);
|
90
|
-
req =
|
91
|
-
DATA_PTR(self) = x;
|
91
|
+
req = d2i_X509_REQ_bio(in, NULL);
|
92
92
|
if (!req) {
|
93
|
-
|
94
|
-
|
95
|
-
DATA_PTR(self) = x;
|
93
|
+
OSSL_BIO_reset(in);
|
94
|
+
req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
|
96
95
|
}
|
97
96
|
BIO_free(in);
|
98
|
-
if (!req)
|
97
|
+
if (!req)
|
98
|
+
ossl_raise(eX509ReqError, "PEM_read_bio_X509_REQ");
|
99
|
+
|
100
|
+
RTYPEDDATA_DATA(self) = req;
|
101
|
+
X509_REQ_free(req_orig);
|
99
102
|
|
100
103
|
return self;
|
101
104
|
}
|