rubysl-openssl 2.10 → 2.11
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 +5 -5
- data/ext/rubysl/openssl/deprecation.rb +7 -3
- data/ext/rubysl/openssl/extconf.rb +148 -103
- data/ext/rubysl/openssl/openssl_missing.c +94 -275
- data/ext/rubysl/openssl/openssl_missing.h +167 -98
- data/ext/rubysl/openssl/ossl.c +266 -212
- data/ext/rubysl/openssl/ossl.h +27 -89
- data/ext/rubysl/openssl/ossl_asn1.c +157 -221
- data/ext/rubysl/openssl/ossl_asn1.h +11 -3
- data/ext/rubysl/openssl/ossl_bio.c +10 -40
- data/ext/rubysl/openssl/ossl_bio.h +1 -2
- data/ext/rubysl/openssl/ossl_bn.c +144 -100
- data/ext/rubysl/openssl/ossl_bn.h +3 -1
- data/ext/rubysl/openssl/ossl_cipher.c +270 -195
- data/ext/rubysl/openssl/ossl_config.c +7 -1
- data/ext/rubysl/openssl/ossl_config.h +0 -1
- data/ext/rubysl/openssl/ossl_digest.c +40 -29
- data/ext/rubysl/openssl/ossl_engine.c +23 -62
- data/ext/rubysl/openssl/ossl_hmac.c +82 -55
- data/ext/rubysl/openssl/ossl_ns_spki.c +22 -22
- data/ext/rubysl/openssl/ossl_ocsp.c +894 -144
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +47 -19
- data/ext/rubysl/openssl/ossl_pkcs5.c +7 -15
- data/ext/rubysl/openssl/ossl_pkcs7.c +38 -15
- data/ext/rubysl/openssl/ossl_pkey.c +151 -99
- data/ext/rubysl/openssl/ossl_pkey.h +123 -29
- data/ext/rubysl/openssl/ossl_pkey_dh.c +143 -92
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +149 -104
- data/ext/rubysl/openssl/ossl_pkey_ec.c +646 -524
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +180 -121
- data/ext/rubysl/openssl/ossl_rand.c +25 -21
- data/ext/rubysl/openssl/ossl_ssl.c +795 -413
- data/ext/rubysl/openssl/ossl_ssl.h +3 -0
- data/ext/rubysl/openssl/ossl_ssl_session.c +83 -77
- data/ext/rubysl/openssl/ossl_version.h +1 -1
- data/ext/rubysl/openssl/ossl_x509.c +92 -8
- data/ext/rubysl/openssl/ossl_x509.h +14 -5
- data/ext/rubysl/openssl/ossl_x509attr.c +77 -41
- data/ext/rubysl/openssl/ossl_x509cert.c +45 -46
- data/ext/rubysl/openssl/ossl_x509crl.c +51 -57
- data/ext/rubysl/openssl/ossl_x509ext.c +39 -33
- data/ext/rubysl/openssl/ossl_x509name.c +68 -45
- data/ext/rubysl/openssl/ossl_x509req.c +32 -38
- data/ext/rubysl/openssl/ossl_x509revoked.c +43 -9
- data/ext/rubysl/openssl/ossl_x509store.c +309 -104
- data/ext/rubysl/openssl/ruby_missing.h +8 -6
- data/lib/openssl/buffering.rb +11 -5
- data/lib/openssl/cipher.rb +23 -15
- data/lib/openssl/digest.rb +7 -10
- data/lib/openssl/pkey.rb +15 -8
- data/lib/openssl/ssl.rb +81 -105
- data/lib/rubysl/openssl.rb +1 -4
- data/lib/rubysl/openssl/version.rb +1 -1
- metadata +3 -4
@@ -86,15 +86,15 @@ ossl_spki_initialize(int argc, VALUE *argv, VALUE self)
|
|
86
86
|
return self;
|
87
87
|
}
|
88
88
|
StringValue(buffer);
|
89
|
-
if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer),
|
89
|
+
if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), RSTRING_LENINT(buffer)))) {
|
90
|
+
ossl_clear_error();
|
90
91
|
p = (unsigned char *)RSTRING_PTR(buffer);
|
91
92
|
if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) {
|
92
93
|
ossl_raise(eSPKIError, NULL);
|
93
94
|
}
|
94
95
|
}
|
95
96
|
NETSCAPE_SPKI_free(DATA_PTR(self));
|
96
|
-
|
97
|
-
ERR_clear_error();
|
97
|
+
SetSPKI(self, spki);
|
98
98
|
|
99
99
|
return self;
|
100
100
|
}
|
@@ -159,8 +159,6 @@ ossl_spki_print(VALUE self)
|
|
159
159
|
{
|
160
160
|
NETSCAPE_SPKI *spki;
|
161
161
|
BIO *out;
|
162
|
-
BUF_MEM *buf;
|
163
|
-
VALUE str;
|
164
162
|
|
165
163
|
GetSPKI(self, spki);
|
166
164
|
if (!(out = BIO_new(BIO_s_mem()))) {
|
@@ -170,11 +168,8 @@ ossl_spki_print(VALUE self)
|
|
170
168
|
BIO_free(out);
|
171
169
|
ossl_raise(eSPKIError, NULL);
|
172
170
|
}
|
173
|
-
BIO_get_mem_ptr(out, &buf);
|
174
|
-
str = rb_str_new(buf->data, buf->length);
|
175
|
-
BIO_free(out);
|
176
171
|
|
177
|
-
return
|
172
|
+
return ossl_membio2str(out);
|
178
173
|
}
|
179
174
|
|
180
175
|
/*
|
@@ -213,12 +208,13 @@ static VALUE
|
|
213
208
|
ossl_spki_set_public_key(VALUE self, VALUE key)
|
214
209
|
{
|
215
210
|
NETSCAPE_SPKI *spki;
|
211
|
+
EVP_PKEY *pkey;
|
216
212
|
|
217
213
|
GetSPKI(self, spki);
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
214
|
+
pkey = GetPKeyPtr(key);
|
215
|
+
ossl_pkey_check_public_key(pkey);
|
216
|
+
if (!NETSCAPE_SPKI_set_pubkey(spki, pkey))
|
217
|
+
ossl_raise(eSPKIError, "NETSCAPE_SPKI_set_pubkey");
|
222
218
|
return key;
|
223
219
|
}
|
224
220
|
|
@@ -312,22 +308,25 @@ static VALUE
|
|
312
308
|
ossl_spki_verify(VALUE self, VALUE key)
|
313
309
|
{
|
314
310
|
NETSCAPE_SPKI *spki;
|
311
|
+
EVP_PKEY *pkey;
|
315
312
|
|
316
313
|
GetSPKI(self, spki);
|
317
|
-
|
318
|
-
|
314
|
+
pkey = GetPKeyPtr(key);
|
315
|
+
ossl_pkey_check_public_key(pkey);
|
316
|
+
switch (NETSCAPE_SPKI_verify(spki, pkey)) {
|
317
|
+
case 0:
|
318
|
+
ossl_clear_error();
|
319
319
|
return Qfalse;
|
320
|
-
|
320
|
+
case 1:
|
321
321
|
return Qtrue;
|
322
|
-
|
323
|
-
ossl_raise(eSPKIError,
|
322
|
+
default:
|
323
|
+
ossl_raise(eSPKIError, "NETSCAPE_SPKI_verify");
|
324
324
|
}
|
325
|
-
return Qnil; /* dummy */
|
326
325
|
}
|
327
326
|
|
328
327
|
/* Document-class: OpenSSL::Netscape::SPKI
|
329
328
|
*
|
330
|
-
* A Simple Public Key Infrastructure implementation (pronounced "
|
329
|
+
* A Simple Public Key Infrastructure implementation (pronounced "spooky").
|
331
330
|
* The structure is defined as
|
332
331
|
* PublicKeyAndChallenge ::= SEQUENCE {
|
333
332
|
* spki SubjectPublicKeyInfo,
|
@@ -353,7 +352,7 @@ ossl_spki_verify(VALUE self, VALUE key)
|
|
353
352
|
* spki.public_key = key.public_key
|
354
353
|
* spki.sign(key, OpenSSL::Digest::SHA256.new)
|
355
354
|
* #send a request containing this to a server generating a certificate
|
356
|
-
* ===
|
355
|
+
* === Verifying an SPKI request
|
357
356
|
* request = #...
|
358
357
|
* spki = OpenSSL::Netscape::SPKI.new request
|
359
358
|
* unless spki.verify(spki.public_key)
|
@@ -380,7 +379,8 @@ void
|
|
380
379
|
Init_ossl_ns_spki(void)
|
381
380
|
{
|
382
381
|
#if 0
|
383
|
-
mOSSL = rb_define_module("OpenSSL");
|
382
|
+
mOSSL = rb_define_module("OpenSSL");
|
383
|
+
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
384
384
|
#endif
|
385
385
|
|
386
386
|
mNetscape = rb_define_module_under(mOSSL, "Netscape");
|
@@ -10,7 +10,7 @@
|
|
10
10
|
*/
|
11
11
|
#include "ossl.h"
|
12
12
|
|
13
|
-
#if defined(
|
13
|
+
#if !defined(OPENSSL_NO_OCSP)
|
14
14
|
|
15
15
|
#define NewOCSPReq(klass) \
|
16
16
|
TypedData_Wrap_Struct((klass), &ossl_ocsp_request_type, 0)
|
@@ -57,6 +57,21 @@
|
|
57
57
|
GetOCSPBasicRes((obj), (res)); \
|
58
58
|
} while (0)
|
59
59
|
|
60
|
+
#define NewOCSPSingleRes(klass) \
|
61
|
+
TypedData_Wrap_Struct((klass), &ossl_ocsp_singleresp_type, 0)
|
62
|
+
#define SetOCSPSingleRes(obj, res) do { \
|
63
|
+
if(!(res)) ossl_raise(rb_eRuntimeError, "SingleResponse wasn't initialized!"); \
|
64
|
+
RTYPEDDATA_DATA(obj) = (res); \
|
65
|
+
} while (0)
|
66
|
+
#define GetOCSPSingleRes(obj, res) do { \
|
67
|
+
TypedData_Get_Struct((obj), OCSP_SINGLERESP, &ossl_ocsp_singleresp_type, (res)); \
|
68
|
+
if(!(res)) ossl_raise(rb_eRuntimeError, "SingleResponse wasn't initialized!"); \
|
69
|
+
} while (0)
|
70
|
+
#define SafeGetOCSPSingleRes(obj, res) do { \
|
71
|
+
OSSL_Check_Kind((obj), cOCSPSingleRes); \
|
72
|
+
GetOCSPSingleRes((obj), (res)); \
|
73
|
+
} while (0)
|
74
|
+
|
60
75
|
#define NewOCSPCertId(klass) \
|
61
76
|
TypedData_Wrap_Struct((klass), &ossl_ocsp_certid_type, 0)
|
62
77
|
#define SetOCSPCertId(obj, cid) do { \
|
@@ -77,6 +92,7 @@ VALUE eOCSPError;
|
|
77
92
|
VALUE cOCSPReq;
|
78
93
|
VALUE cOCSPRes;
|
79
94
|
VALUE cOCSPBasicRes;
|
95
|
+
VALUE cOCSPSingleRes;
|
80
96
|
VALUE cOCSPCertId;
|
81
97
|
|
82
98
|
static void
|
@@ -121,6 +137,20 @@ static const rb_data_type_t ossl_ocsp_basicresp_type = {
|
|
121
137
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
122
138
|
};
|
123
139
|
|
140
|
+
static void
|
141
|
+
ossl_ocsp_singleresp_free(void *ptr)
|
142
|
+
{
|
143
|
+
OCSP_SINGLERESP_free(ptr);
|
144
|
+
}
|
145
|
+
|
146
|
+
static const rb_data_type_t ossl_ocsp_singleresp_type = {
|
147
|
+
"OpenSSL/OCSP/SINGLERESP",
|
148
|
+
{
|
149
|
+
0, ossl_ocsp_singleresp_free,
|
150
|
+
},
|
151
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
152
|
+
};
|
153
|
+
|
124
154
|
static void
|
125
155
|
ossl_ocsp_certid_free(void *ptr)
|
126
156
|
{
|
@@ -163,6 +193,25 @@ ossl_ocspreq_alloc(VALUE klass)
|
|
163
193
|
return obj;
|
164
194
|
}
|
165
195
|
|
196
|
+
static VALUE
|
197
|
+
ossl_ocspreq_initialize_copy(VALUE self, VALUE other)
|
198
|
+
{
|
199
|
+
OCSP_REQUEST *req, *req_old, *req_new;
|
200
|
+
|
201
|
+
rb_check_frozen(self);
|
202
|
+
GetOCSPReq(self, req_old);
|
203
|
+
SafeGetOCSPReq(other, req);
|
204
|
+
|
205
|
+
req_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_REQUEST), req);
|
206
|
+
if (!req_new)
|
207
|
+
ossl_raise(eOCSPError, "ASN1_item_dup");
|
208
|
+
|
209
|
+
SetOCSPReq(self, req_new);
|
210
|
+
OCSP_REQUEST_free(req_old);
|
211
|
+
|
212
|
+
return self;
|
213
|
+
}
|
214
|
+
|
166
215
|
/*
|
167
216
|
* call-seq:
|
168
217
|
* OpenSSL::OCSP::Request.new -> request
|
@@ -176,19 +225,20 @@ static VALUE
|
|
176
225
|
ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
|
177
226
|
{
|
178
227
|
VALUE arg;
|
228
|
+
OCSP_REQUEST *req, *req_new;
|
179
229
|
const unsigned char *p;
|
180
230
|
|
181
231
|
rb_scan_args(argc, argv, "01", &arg);
|
182
232
|
if(!NIL_P(arg)){
|
183
|
-
|
233
|
+
GetOCSPReq(self, req);
|
184
234
|
arg = ossl_to_der_if_possible(arg);
|
185
235
|
StringValue(arg);
|
186
|
-
p = (unsigned char*)RSTRING_PTR(arg);
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
236
|
+
p = (unsigned char *)RSTRING_PTR(arg);
|
237
|
+
req_new = d2i_OCSP_REQUEST(NULL, &p, RSTRING_LEN(arg));
|
238
|
+
if (!req_new)
|
239
|
+
ossl_raise(eOCSPError, "d2i_OCSP_REQUEST");
|
240
|
+
SetOCSPReq(self, req_new);
|
241
|
+
OCSP_REQUEST_free(req);
|
192
242
|
}
|
193
243
|
|
194
244
|
return self;
|
@@ -319,49 +369,61 @@ ossl_ocspreq_get_certid(VALUE self)
|
|
319
369
|
|
320
370
|
/*
|
321
371
|
* call-seq:
|
322
|
-
* request.sign(
|
323
|
-
* request.sign(signer_cert, signer_key, certificates) -> self
|
324
|
-
* request.sign(signer_cert, signer_key, certificates, flags) -> self
|
372
|
+
* request.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
|
325
373
|
*
|
326
|
-
* Signs this OCSP request using +
|
327
|
-
* +
|
328
|
-
* the request
|
374
|
+
* Signs this OCSP request using +cert+, +key+ and optional +digest+. If
|
375
|
+
* +digest+ is not specified, SHA-1 is used. +certs+ is an optional Array of
|
376
|
+
* additional certificates which are included in the request in addition to
|
377
|
+
* the signer certificate. Note that if +certs+ is nil or not given, flag
|
378
|
+
* OpenSSL::OCSP::NOCERTS is enabled. Pass an empty array to include only the
|
379
|
+
* signer certificate.
|
380
|
+
*
|
381
|
+
* +flags+ can be a bitwise OR of the following constants:
|
382
|
+
*
|
383
|
+
* OpenSSL::OCSP::NOCERTS::
|
384
|
+
* Don't include any certificates in the request. +certs+ will be ignored.
|
329
385
|
*/
|
330
|
-
|
331
386
|
static VALUE
|
332
387
|
ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
|
333
388
|
{
|
334
|
-
VALUE signer_cert, signer_key, certs, flags;
|
389
|
+
VALUE signer_cert, signer_key, certs, flags, digest;
|
335
390
|
OCSP_REQUEST *req;
|
336
391
|
X509 *signer;
|
337
392
|
EVP_PKEY *key;
|
338
|
-
STACK_OF(X509) *x509s;
|
339
|
-
unsigned long flg;
|
393
|
+
STACK_OF(X509) *x509s = NULL;
|
394
|
+
unsigned long flg = 0;
|
395
|
+
const EVP_MD *md;
|
340
396
|
int ret;
|
341
397
|
|
342
|
-
rb_scan_args(argc, argv, "
|
398
|
+
rb_scan_args(argc, argv, "23", &signer_cert, &signer_key, &certs, &flags, &digest);
|
399
|
+
GetOCSPReq(self, req);
|
343
400
|
signer = GetX509CertPtr(signer_cert);
|
344
401
|
key = GetPrivPKeyPtr(signer_key);
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
402
|
+
if (!NIL_P(flags))
|
403
|
+
flg = NUM2INT(flags);
|
404
|
+
if (NIL_P(digest))
|
405
|
+
md = EVP_sha1();
|
406
|
+
else
|
407
|
+
md = GetDigestPtr(digest);
|
408
|
+
if (NIL_P(certs))
|
409
|
+
flg |= OCSP_NOCERTS;
|
410
|
+
else
|
411
|
+
x509s = ossl_x509_ary2sk(certs);
|
412
|
+
|
413
|
+
ret = OCSP_request_sign(req, signer, key, md, x509s, flg);
|
353
414
|
sk_X509_pop_free(x509s, X509_free);
|
354
|
-
if(!ret) ossl_raise(eOCSPError, NULL);
|
415
|
+
if (!ret) ossl_raise(eOCSPError, NULL);
|
355
416
|
|
356
417
|
return self;
|
357
418
|
}
|
358
419
|
|
359
420
|
/*
|
360
421
|
* call-seq:
|
361
|
-
* request.verify(certificates, store)
|
362
|
-
* request.verify(certificates, store, flags) -> true or false
|
422
|
+
* request.verify(certificates, store, flags = 0) -> true or false
|
363
423
|
*
|
364
|
-
* Verifies this request using the given +certificates+ and
|
424
|
+
* Verifies this request using the given +certificates+ and +store+.
|
425
|
+
* +certificates+ is an array of OpenSSL::X509::Certificate, +store+ is an
|
426
|
+
* OpenSSL::X509::Store.
|
365
427
|
*/
|
366
428
|
|
367
429
|
static VALUE
|
@@ -374,15 +436,16 @@ ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)
|
|
374
436
|
int flg, result;
|
375
437
|
|
376
438
|
rb_scan_args(argc, argv, "21", &certs, &store, &flags);
|
439
|
+
GetOCSPReq(self, req);
|
377
440
|
x509st = GetX509StorePtr(store);
|
378
441
|
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
|
379
442
|
x509s = ossl_x509_ary2sk(certs);
|
380
|
-
GetOCSPReq(self, req);
|
381
443
|
result = OCSP_request_verify(req, x509s, x509st, flg);
|
382
444
|
sk_X509_pop_free(x509s, X509_free);
|
383
|
-
if(
|
445
|
+
if (result <= 0)
|
446
|
+
ossl_clear_error();
|
384
447
|
|
385
|
-
return result ? Qtrue : Qfalse;
|
448
|
+
return result > 0 ? Qtrue : Qfalse;
|
386
449
|
}
|
387
450
|
|
388
451
|
/*
|
@@ -451,6 +514,25 @@ ossl_ocspres_alloc(VALUE klass)
|
|
451
514
|
return obj;
|
452
515
|
}
|
453
516
|
|
517
|
+
static VALUE
|
518
|
+
ossl_ocspres_initialize_copy(VALUE self, VALUE other)
|
519
|
+
{
|
520
|
+
OCSP_RESPONSE *res, *res_old, *res_new;
|
521
|
+
|
522
|
+
rb_check_frozen(self);
|
523
|
+
GetOCSPRes(self, res_old);
|
524
|
+
SafeGetOCSPRes(other, res);
|
525
|
+
|
526
|
+
res_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_RESPONSE), res);
|
527
|
+
if (!res_new)
|
528
|
+
ossl_raise(eOCSPError, "ASN1_item_dup");
|
529
|
+
|
530
|
+
SetOCSPRes(self, res_new);
|
531
|
+
OCSP_RESPONSE_free(res_old);
|
532
|
+
|
533
|
+
return self;
|
534
|
+
}
|
535
|
+
|
454
536
|
/*
|
455
537
|
* call-seq:
|
456
538
|
* OpenSSL::OCSP::Response.new -> response
|
@@ -464,19 +546,20 @@ static VALUE
|
|
464
546
|
ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)
|
465
547
|
{
|
466
548
|
VALUE arg;
|
549
|
+
OCSP_RESPONSE *res, *res_new;
|
467
550
|
const unsigned char *p;
|
468
551
|
|
469
552
|
rb_scan_args(argc, argv, "01", &arg);
|
470
553
|
if(!NIL_P(arg)){
|
471
|
-
|
554
|
+
GetOCSPRes(self, res);
|
472
555
|
arg = ossl_to_der_if_possible(arg);
|
473
556
|
StringValue(arg);
|
474
557
|
p = (unsigned char *)RSTRING_PTR(arg);
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
558
|
+
res_new = d2i_OCSP_RESPONSE(NULL, &p, RSTRING_LEN(arg));
|
559
|
+
if (!res_new)
|
560
|
+
ossl_raise(eOCSPError, "d2i_OCSP_RESPONSE");
|
561
|
+
SetOCSPRes(self, res_new);
|
562
|
+
OCSP_RESPONSE_free(res);
|
480
563
|
}
|
481
564
|
|
482
565
|
return self;
|
@@ -587,16 +670,53 @@ ossl_ocspbres_alloc(VALUE klass)
|
|
587
670
|
return obj;
|
588
671
|
}
|
589
672
|
|
673
|
+
static VALUE
|
674
|
+
ossl_ocspbres_initialize_copy(VALUE self, VALUE other)
|
675
|
+
{
|
676
|
+
OCSP_BASICRESP *bs, *bs_old, *bs_new;
|
677
|
+
|
678
|
+
rb_check_frozen(self);
|
679
|
+
GetOCSPBasicRes(self, bs_old);
|
680
|
+
SafeGetOCSPBasicRes(other, bs);
|
681
|
+
|
682
|
+
bs_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
|
683
|
+
if (!bs_new)
|
684
|
+
ossl_raise(eOCSPError, "ASN1_item_dup");
|
685
|
+
|
686
|
+
SetOCSPBasicRes(self, bs_new);
|
687
|
+
OCSP_BASICRESP_free(bs_old);
|
688
|
+
|
689
|
+
return self;
|
690
|
+
}
|
691
|
+
|
590
692
|
/*
|
591
693
|
* call-seq:
|
592
|
-
* OpenSSL::OCSP::BasicResponse.new(
|
694
|
+
* OpenSSL::OCSP::BasicResponse.new(der_string = nil) -> basic_response
|
593
695
|
*
|
594
|
-
* Creates a new BasicResponse
|
696
|
+
* Creates a new BasicResponse. If +der_string+ is given, decodes +der_string+
|
697
|
+
* as DER.
|
595
698
|
*/
|
596
699
|
|
597
700
|
static VALUE
|
598
701
|
ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
|
599
702
|
{
|
703
|
+
VALUE arg;
|
704
|
+
OCSP_BASICRESP *res, *res_new;
|
705
|
+
const unsigned char *p;
|
706
|
+
|
707
|
+
rb_scan_args(argc, argv, "01", &arg);
|
708
|
+
if (!NIL_P(arg)) {
|
709
|
+
GetOCSPBasicRes(self, res);
|
710
|
+
arg = ossl_to_der_if_possible(arg);
|
711
|
+
StringValue(arg);
|
712
|
+
p = (unsigned char *)RSTRING_PTR(arg);
|
713
|
+
res_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg));
|
714
|
+
if (!res_new)
|
715
|
+
ossl_raise(eOCSPError, "d2i_OCSP_BASICRESP");
|
716
|
+
SetOCSPBasicRes(self, res_new);
|
717
|
+
OCSP_BASICRESP_free(res);
|
718
|
+
}
|
719
|
+
|
600
720
|
return self;
|
601
721
|
}
|
602
722
|
|
@@ -652,22 +772,49 @@ ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
|
|
652
772
|
return self;
|
653
773
|
}
|
654
774
|
|
775
|
+
static VALUE
|
776
|
+
add_status_convert_time(VALUE obj)
|
777
|
+
{
|
778
|
+
ASN1_TIME *time;
|
779
|
+
|
780
|
+
if (RB_INTEGER_TYPE_P(obj))
|
781
|
+
time = X509_gmtime_adj(NULL, NUM2INT(obj));
|
782
|
+
else
|
783
|
+
time = ossl_x509_time_adjust(NULL, obj);
|
784
|
+
|
785
|
+
if (!time)
|
786
|
+
ossl_raise(eOCSPError, NULL);
|
787
|
+
|
788
|
+
return (VALUE)time;
|
789
|
+
}
|
790
|
+
|
655
791
|
/*
|
656
792
|
* call-seq:
|
657
793
|
* basic_response.add_status(certificate_id, status, reason, revocation_time, this_update, next_update, extensions) -> basic_response
|
658
794
|
*
|
659
|
-
* Adds a
|
660
|
-
*
|
661
|
-
* revocation, if any.
|
795
|
+
* Adds a certificate status for +certificate_id+. +status+ is the status, and
|
796
|
+
* must be one of these:
|
662
797
|
*
|
663
|
-
*
|
664
|
-
*
|
665
|
-
*
|
798
|
+
* - OpenSSL::OCSP::V_CERTSTATUS_GOOD
|
799
|
+
* - OpenSSL::OCSP::V_CERTSTATUS_REVOKED
|
800
|
+
* - OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
|
666
801
|
*
|
667
|
-
* +
|
668
|
-
*
|
802
|
+
* +reason+ and +revocation_time+ can be given only when +status+ is
|
803
|
+
* OpenSSL::OCSP::V_CERTSTATUS_REVOKED. +reason+ describes the reason for the
|
804
|
+
* revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants.
|
805
|
+
* +revocation_time+ is the time when the certificate is revoked.
|
806
|
+
*
|
807
|
+
* +this_update+ and +next_update+ indicate the time at which ths status is
|
808
|
+
* verified to be correct and the time at or before which newer information
|
809
|
+
* will be available, respectively. +next_update+ is optional.
|
810
|
+
*
|
811
|
+
* +extensions+ is an Array of OpenSSL::X509::Extension to be included in the
|
812
|
+
* SingleResponse. This is also optional.
|
813
|
+
*
|
814
|
+
* Note that the times, +revocation_time+, +this_update+ and +next_update+
|
815
|
+
* can be specified in either of Integer or Time object. If they are Integer, it
|
816
|
+
* is treated as the relative seconds from the current time.
|
669
817
|
*/
|
670
|
-
|
671
818
|
static VALUE
|
672
819
|
ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
|
673
820
|
VALUE reason, VALUE revtime,
|
@@ -676,36 +823,37 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
|
|
676
823
|
OCSP_BASICRESP *bs;
|
677
824
|
OCSP_SINGLERESP *single;
|
678
825
|
OCSP_CERTID *id;
|
679
|
-
ASN1_TIME *ths, *nxt, *rev;
|
680
|
-
int st, rsn, error, rstatus = 0;
|
826
|
+
ASN1_TIME *ths = NULL, *nxt = NULL, *rev = NULL;
|
827
|
+
int st, rsn = 0, error = 0, rstatus = 0;
|
681
828
|
long i;
|
682
829
|
VALUE tmp;
|
683
830
|
|
831
|
+
GetOCSPBasicRes(self, bs);
|
832
|
+
SafeGetOCSPCertId(cid, id);
|
684
833
|
st = NUM2INT(status);
|
685
|
-
|
686
|
-
|
687
|
-
/* All ary's members should be X509Extension */
|
688
|
-
Check_Type(ext, T_ARRAY);
|
834
|
+
if (!NIL_P(ext)) { /* All ext's members must be X509::Extension */
|
835
|
+
ext = rb_check_array_type(ext);
|
689
836
|
for (i = 0; i < RARRAY_LEN(ext); i++)
|
690
837
|
OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext);
|
691
838
|
}
|
692
839
|
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
840
|
+
if (st == V_OCSP_CERTSTATUS_REVOKED) {
|
841
|
+
rsn = NUM2INT(reason);
|
842
|
+
tmp = rb_protect(add_status_convert_time, revtime, &rstatus);
|
843
|
+
if (rstatus) goto err;
|
844
|
+
rev = (ASN1_TIME *)tmp;
|
845
|
+
}
|
846
|
+
|
847
|
+
tmp = rb_protect(add_status_convert_time, thisupd, &rstatus);
|
848
|
+
if (rstatus) goto err;
|
849
|
+
ths = (ASN1_TIME *)tmp;
|
850
|
+
|
851
|
+
if (!NIL_P(nextupd)) {
|
852
|
+
tmp = rb_protect(add_status_convert_time, nextupd, &rstatus);
|
853
|
+
if (rstatus) goto err;
|
854
|
+
nxt = (ASN1_TIME *)tmp;
|
699
855
|
}
|
700
|
-
tmp = rb_protect(rb_Integer, thisupd, &rstatus);
|
701
|
-
if(rstatus) goto err;
|
702
|
-
ths = X509_gmtime_adj(NULL, NUM2INT(tmp));
|
703
|
-
tmp = rb_protect(rb_Integer, nextupd, &rstatus);
|
704
|
-
if(rstatus) goto err;
|
705
|
-
nxt = X509_gmtime_adj(NULL, NUM2INT(tmp));
|
706
856
|
|
707
|
-
GetOCSPBasicRes(self, bs);
|
708
|
-
SafeGetOCSPCertId(cid, id);
|
709
857
|
if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){
|
710
858
|
error = 1;
|
711
859
|
goto err;
|
@@ -713,16 +861,13 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
|
|
713
861
|
|
714
862
|
if(!NIL_P(ext)){
|
715
863
|
X509_EXTENSION *x509ext;
|
716
|
-
|
717
|
-
single->singleExtensions = NULL;
|
864
|
+
|
718
865
|
for(i = 0; i < RARRAY_LEN(ext); i++){
|
719
|
-
x509ext =
|
866
|
+
x509ext = GetX509ExtPtr(RARRAY_AREF(ext, i));
|
720
867
|
if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
|
721
|
-
X509_EXTENSION_free(x509ext);
|
722
868
|
error = 1;
|
723
869
|
goto err;
|
724
870
|
}
|
725
|
-
X509_EXTENSION_free(x509ext);
|
726
871
|
}
|
727
872
|
}
|
728
873
|
|
@@ -741,11 +886,13 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
|
|
741
886
|
* basic_response.status -> statuses
|
742
887
|
*
|
743
888
|
* Returns an Array of statuses for this response. Each status contains a
|
744
|
-
* CertificateId, the status (0 for good, 1 for revoked, 2 for unknown), the
|
745
|
-
* the status, the revocation time, the time of this update, the time
|
746
|
-
* next update and a list of OpenSSL::X509::Extensions.
|
889
|
+
* CertificateId, the status (0 for good, 1 for revoked, 2 for unknown), the
|
890
|
+
* reason for the status, the revocation time, the time of this update, the time
|
891
|
+
* for the next update and a list of OpenSSL::X509::Extensions.
|
892
|
+
*
|
893
|
+
* This should be superseded by BasicResponse#responses and #find_response that
|
894
|
+
* return SingleResponse.
|
747
895
|
*/
|
748
|
-
|
749
896
|
static VALUE
|
750
897
|
ossl_ocspbres_get_status(VALUE self)
|
751
898
|
{
|
@@ -769,7 +916,7 @@ ossl_ocspbres_get_status(VALUE self)
|
|
769
916
|
status = OCSP_single_get0_status(single, &reason, &revtime,
|
770
917
|
&thisupd, &nextupd);
|
771
918
|
if(status < 0) continue;
|
772
|
-
if(!(cid = OCSP_CERTID_dup(single
|
919
|
+
if(!(cid = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(single)))) /* FIXME */
|
773
920
|
ossl_raise(eOCSPError, NULL);
|
774
921
|
ary = rb_ary_new();
|
775
922
|
rb_ary_push(ary, ossl_ocspcertid_new(cid));
|
@@ -791,75 +938,512 @@ ossl_ocspbres_get_status(VALUE self)
|
|
791
938
|
return ret;
|
792
939
|
}
|
793
940
|
|
941
|
+
static VALUE ossl_ocspsres_new(OCSP_SINGLERESP *);
|
942
|
+
|
794
943
|
/*
|
795
944
|
* call-seq:
|
796
|
-
* basic_response.
|
797
|
-
* basic_response.sign(signer_cert, signer_key, certificates) -> self
|
798
|
-
* basic_response.sign(signer_cert, signer_key, certificates, flags) -> self
|
945
|
+
* basic_response.responses -> Array of SingleResponse
|
799
946
|
*
|
800
|
-
*
|
801
|
-
|
947
|
+
* Returns an Array of SingleResponse for this BasicResponse.
|
948
|
+
*/
|
949
|
+
|
950
|
+
static VALUE
|
951
|
+
ossl_ocspbres_get_responses(VALUE self)
|
952
|
+
{
|
953
|
+
OCSP_BASICRESP *bs;
|
954
|
+
VALUE ret;
|
955
|
+
int count, i;
|
956
|
+
|
957
|
+
GetOCSPBasicRes(self, bs);
|
958
|
+
count = OCSP_resp_count(bs);
|
959
|
+
ret = rb_ary_new2(count);
|
960
|
+
|
961
|
+
for (i = 0; i < count; i++) {
|
962
|
+
OCSP_SINGLERESP *sres, *sres_new;
|
963
|
+
|
964
|
+
sres = OCSP_resp_get0(bs, i);
|
965
|
+
sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
|
966
|
+
if (!sres_new)
|
967
|
+
ossl_raise(eOCSPError, "ASN1_item_dup");
|
968
|
+
|
969
|
+
rb_ary_push(ret, ossl_ocspsres_new(sres_new));
|
970
|
+
}
|
971
|
+
|
972
|
+
return ret;
|
973
|
+
}
|
974
|
+
|
975
|
+
|
976
|
+
/*
|
977
|
+
* call-seq:
|
978
|
+
* basic_response.find_response(certificate_id) -> SingleResponse | nil
|
979
|
+
*
|
980
|
+
* Returns a SingleResponse whose CertId matches with +certificate_id+, or nil
|
981
|
+
* if this BasicResponse does not contain it.
|
982
|
+
*/
|
983
|
+
static VALUE
|
984
|
+
ossl_ocspbres_find_response(VALUE self, VALUE target)
|
985
|
+
{
|
986
|
+
OCSP_BASICRESP *bs;
|
987
|
+
OCSP_SINGLERESP *sres, *sres_new;
|
988
|
+
OCSP_CERTID *id;
|
989
|
+
int n;
|
990
|
+
|
991
|
+
SafeGetOCSPCertId(target, id);
|
992
|
+
GetOCSPBasicRes(self, bs);
|
993
|
+
|
994
|
+
if ((n = OCSP_resp_find(bs, id, -1)) == -1)
|
995
|
+
return Qnil;
|
996
|
+
|
997
|
+
sres = OCSP_resp_get0(bs, n);
|
998
|
+
sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
|
999
|
+
if (!sres_new)
|
1000
|
+
ossl_raise(eOCSPError, "ASN1_item_dup");
|
1001
|
+
|
1002
|
+
return ossl_ocspsres_new(sres_new);
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
/*
|
1006
|
+
* call-seq:
|
1007
|
+
* basic_response.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
|
1008
|
+
*
|
1009
|
+
* Signs this OCSP response using the +cert+, +key+ and optional +digest+. This
|
1010
|
+
* behaves in the similar way as OpenSSL::OCSP::Request#sign.
|
1011
|
+
*
|
1012
|
+
* +flags+ can include:
|
1013
|
+
* OpenSSL::OCSP::NOCERTS:: don't include certificates
|
1014
|
+
* OpenSSL::OCSP::NOTIME:: don't set producedAt
|
1015
|
+
* OpenSSL::OCSP::RESPID_KEY:: use signer's public key hash as responderID
|
802
1016
|
*/
|
803
1017
|
|
804
1018
|
static VALUE
|
805
1019
|
ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
|
806
1020
|
{
|
807
|
-
VALUE signer_cert, signer_key, certs, flags;
|
1021
|
+
VALUE signer_cert, signer_key, certs, flags, digest;
|
808
1022
|
OCSP_BASICRESP *bs;
|
809
1023
|
X509 *signer;
|
810
1024
|
EVP_PKEY *key;
|
811
|
-
STACK_OF(X509) *x509s;
|
812
|
-
unsigned long flg;
|
1025
|
+
STACK_OF(X509) *x509s = NULL;
|
1026
|
+
unsigned long flg = 0;
|
1027
|
+
const EVP_MD *md;
|
813
1028
|
int ret;
|
814
1029
|
|
815
|
-
rb_scan_args(argc, argv, "
|
1030
|
+
rb_scan_args(argc, argv, "23", &signer_cert, &signer_key, &certs, &flags, &digest);
|
1031
|
+
GetOCSPBasicRes(self, bs);
|
816
1032
|
signer = GetX509CertPtr(signer_cert);
|
817
1033
|
key = GetPrivPKeyPtr(signer_key);
|
818
|
-
|
819
|
-
|
820
|
-
|
1034
|
+
if (!NIL_P(flags))
|
1035
|
+
flg = NUM2INT(flags);
|
1036
|
+
if (NIL_P(digest))
|
1037
|
+
md = EVP_sha1();
|
1038
|
+
else
|
1039
|
+
md = GetDigestPtr(digest);
|
1040
|
+
if (NIL_P(certs))
|
821
1041
|
flg |= OCSP_NOCERTS;
|
822
|
-
|
823
|
-
else{
|
1042
|
+
else
|
824
1043
|
x509s = ossl_x509_ary2sk(certs);
|
825
|
-
|
826
|
-
|
827
|
-
ret = OCSP_basic_sign(bs, signer, key, EVP_sha1(), x509s, flg);
|
1044
|
+
|
1045
|
+
ret = OCSP_basic_sign(bs, signer, key, md, x509s, flg);
|
828
1046
|
sk_X509_pop_free(x509s, X509_free);
|
829
|
-
if(!ret) ossl_raise(eOCSPError, NULL);
|
1047
|
+
if (!ret) ossl_raise(eOCSPError, NULL);
|
830
1048
|
|
831
1049
|
return self;
|
832
1050
|
}
|
833
1051
|
|
834
1052
|
/*
|
835
1053
|
* call-seq:
|
836
|
-
* basic_response.verify(certificates, store) -> true or false
|
837
|
-
* basic_response.verify(certificates, store, flags) -> true or false
|
1054
|
+
* basic_response.verify(certificates, store, flags = 0) -> true or false
|
838
1055
|
*
|
839
|
-
* Verifies the signature of the response using the given +certificates
|
840
|
-
* +store
|
1056
|
+
* Verifies the signature of the response using the given +certificates+ and
|
1057
|
+
* +store+. This works in the similar way as OpenSSL::OCSP::Request#verify.
|
841
1058
|
*/
|
842
1059
|
static VALUE
|
843
1060
|
ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
|
844
1061
|
{
|
845
|
-
VALUE certs, store, flags
|
1062
|
+
VALUE certs, store, flags;
|
846
1063
|
OCSP_BASICRESP *bs;
|
847
1064
|
STACK_OF(X509) *x509s;
|
848
1065
|
X509_STORE *x509st;
|
849
|
-
int flg;
|
1066
|
+
int flg, result;
|
850
1067
|
|
851
1068
|
rb_scan_args(argc, argv, "21", &certs, &store, &flags);
|
1069
|
+
GetOCSPBasicRes(self, bs);
|
852
1070
|
x509st = GetX509StorePtr(store);
|
853
1071
|
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
|
854
1072
|
x509s = ossl_x509_ary2sk(certs);
|
855
|
-
|
856
|
-
|
1073
|
+
#if (OPENSSL_VERSION_NUMBER < 0x1000202fL) || defined(LIBRESSL_VERSION_NUMBER)
|
1074
|
+
/*
|
1075
|
+
* OpenSSL had a bug that it doesn't use the certificates in x509s for
|
1076
|
+
* verifying the chain. This can be a problem when the response is signed by
|
1077
|
+
* a certificate issued by an intermediate CA.
|
1078
|
+
*
|
1079
|
+
* root_ca
|
1080
|
+
* |
|
1081
|
+
* intermediate_ca
|
1082
|
+
* |-------------|
|
1083
|
+
* end_entity ocsp_signer
|
1084
|
+
*
|
1085
|
+
* When the certificate hierarchy is like this, and the response contains
|
1086
|
+
* only ocsp_signer certificate, the following code wrongly fails.
|
1087
|
+
*
|
1088
|
+
* store = OpenSSL::X509::Store.new; store.add_cert(root_ca)
|
1089
|
+
* basic_response.verify([intermediate_ca], store)
|
1090
|
+
*
|
1091
|
+
* So add the certificates in x509s to the embedded certificates list first.
|
1092
|
+
*
|
1093
|
+
* This is fixed in OpenSSL 0.9.8zg, 1.0.0s, 1.0.1n, 1.0.2b. But it still
|
1094
|
+
* exists in LibreSSL 2.1.10, 2.2.9, 2.3.6, 2.4.1.
|
1095
|
+
*/
|
1096
|
+
if (!(flg & (OCSP_NOCHAIN | OCSP_NOVERIFY)) &&
|
1097
|
+
sk_X509_num(x509s) && sk_X509_num(bs->certs)) {
|
1098
|
+
int i;
|
1099
|
+
|
1100
|
+
bs = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
|
1101
|
+
if (!bs) {
|
1102
|
+
sk_X509_pop_free(x509s, X509_free);
|
1103
|
+
ossl_raise(eOCSPError, "ASN1_item_dup");
|
1104
|
+
}
|
1105
|
+
|
1106
|
+
for (i = 0; i < sk_X509_num(x509s); i++) {
|
1107
|
+
if (!OCSP_basic_add1_cert(bs, sk_X509_value(x509s, i))) {
|
1108
|
+
sk_X509_pop_free(x509s, X509_free);
|
1109
|
+
OCSP_BASICRESP_free(bs);
|
1110
|
+
ossl_raise(eOCSPError, "OCSP_basic_add1_cert");
|
1111
|
+
}
|
1112
|
+
}
|
1113
|
+
result = OCSP_basic_verify(bs, x509s, x509st, flg);
|
1114
|
+
OCSP_BASICRESP_free(bs);
|
1115
|
+
}
|
1116
|
+
else {
|
1117
|
+
result = OCSP_basic_verify(bs, x509s, x509st, flg);
|
1118
|
+
}
|
1119
|
+
#else
|
1120
|
+
result = OCSP_basic_verify(bs, x509s, x509st, flg);
|
1121
|
+
#endif
|
857
1122
|
sk_X509_pop_free(x509s, X509_free);
|
858
|
-
if(
|
1123
|
+
if (result <= 0)
|
1124
|
+
ossl_clear_error();
|
1125
|
+
|
1126
|
+
return result > 0 ? Qtrue : Qfalse;
|
1127
|
+
}
|
1128
|
+
|
1129
|
+
/*
|
1130
|
+
* call-seq:
|
1131
|
+
* basic_response.to_der -> String
|
1132
|
+
*
|
1133
|
+
* Encodes this basic response into a DER-encoded string.
|
1134
|
+
*/
|
1135
|
+
static VALUE
|
1136
|
+
ossl_ocspbres_to_der(VALUE self)
|
1137
|
+
{
|
1138
|
+
OCSP_BASICRESP *res;
|
1139
|
+
VALUE str;
|
1140
|
+
long len;
|
1141
|
+
unsigned char *p;
|
859
1142
|
|
860
|
-
|
1143
|
+
GetOCSPBasicRes(self, res);
|
1144
|
+
if ((len = i2d_OCSP_BASICRESP(res, NULL)) <= 0)
|
1145
|
+
ossl_raise(eOCSPError, NULL);
|
1146
|
+
str = rb_str_new(0, len);
|
1147
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
1148
|
+
if (i2d_OCSP_BASICRESP(res, &p) <= 0)
|
1149
|
+
ossl_raise(eOCSPError, NULL);
|
1150
|
+
ossl_str_adjust(str, p);
|
1151
|
+
|
1152
|
+
return str;
|
861
1153
|
}
|
862
1154
|
|
1155
|
+
/*
|
1156
|
+
* OCSP::SingleResponse
|
1157
|
+
*/
|
1158
|
+
static VALUE
|
1159
|
+
ossl_ocspsres_new(OCSP_SINGLERESP *sres)
|
1160
|
+
{
|
1161
|
+
VALUE obj;
|
1162
|
+
|
1163
|
+
obj = NewOCSPSingleRes(cOCSPSingleRes);
|
1164
|
+
SetOCSPSingleRes(obj, sres);
|
1165
|
+
|
1166
|
+
return obj;
|
1167
|
+
}
|
1168
|
+
|
1169
|
+
static VALUE
|
1170
|
+
ossl_ocspsres_alloc(VALUE klass)
|
1171
|
+
{
|
1172
|
+
OCSP_SINGLERESP *sres;
|
1173
|
+
VALUE obj;
|
1174
|
+
|
1175
|
+
obj = NewOCSPSingleRes(klass);
|
1176
|
+
if (!(sres = OCSP_SINGLERESP_new()))
|
1177
|
+
ossl_raise(eOCSPError, NULL);
|
1178
|
+
SetOCSPSingleRes(obj, sres);
|
1179
|
+
|
1180
|
+
return obj;
|
1181
|
+
}
|
1182
|
+
|
1183
|
+
/*
|
1184
|
+
* call-seq:
|
1185
|
+
* OpenSSL::OCSP::SingleResponse.new(der_string) -> SingleResponse
|
1186
|
+
*
|
1187
|
+
* Creates a new SingleResponse from +der_string+.
|
1188
|
+
*/
|
1189
|
+
static VALUE
|
1190
|
+
ossl_ocspsres_initialize(VALUE self, VALUE arg)
|
1191
|
+
{
|
1192
|
+
OCSP_SINGLERESP *res, *res_new;
|
1193
|
+
const unsigned char *p;
|
1194
|
+
|
1195
|
+
arg = ossl_to_der_if_possible(arg);
|
1196
|
+
StringValue(arg);
|
1197
|
+
GetOCSPSingleRes(self, res);
|
1198
|
+
|
1199
|
+
p = (unsigned char*)RSTRING_PTR(arg);
|
1200
|
+
res_new = d2i_OCSP_SINGLERESP(NULL, &p, RSTRING_LEN(arg));
|
1201
|
+
if (!res_new)
|
1202
|
+
ossl_raise(eOCSPError, "d2i_OCSP_SINGLERESP");
|
1203
|
+
SetOCSPSingleRes(self, res_new);
|
1204
|
+
OCSP_SINGLERESP_free(res);
|
1205
|
+
|
1206
|
+
return self;
|
1207
|
+
}
|
1208
|
+
|
1209
|
+
static VALUE
|
1210
|
+
ossl_ocspsres_initialize_copy(VALUE self, VALUE other)
|
1211
|
+
{
|
1212
|
+
OCSP_SINGLERESP *sres, *sres_old, *sres_new;
|
1213
|
+
|
1214
|
+
rb_check_frozen(self);
|
1215
|
+
GetOCSPSingleRes(self, sres_old);
|
1216
|
+
SafeGetOCSPSingleRes(other, sres);
|
1217
|
+
|
1218
|
+
sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
|
1219
|
+
if (!sres_new)
|
1220
|
+
ossl_raise(eOCSPError, "ASN1_item_dup");
|
1221
|
+
|
1222
|
+
SetOCSPSingleRes(self, sres_new);
|
1223
|
+
OCSP_SINGLERESP_free(sres_old);
|
1224
|
+
|
1225
|
+
return self;
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
/*
|
1229
|
+
* call-seq:
|
1230
|
+
* single_response.check_validity(nsec = 0, maxsec = -1) -> true | false
|
1231
|
+
*
|
1232
|
+
* Checks the validity of thisUpdate and nextUpdate fields of this
|
1233
|
+
* SingleResponse. This checks the current time is within the range thisUpdate
|
1234
|
+
* to nextUpdate.
|
1235
|
+
*
|
1236
|
+
* It is possible that the OCSP request takes a few seconds or the time is not
|
1237
|
+
* accurate. To avoid rejecting a valid response, this method allows the times
|
1238
|
+
* to be within +nsec+ of the current time.
|
1239
|
+
*
|
1240
|
+
* Some responders don't set the nextUpdate field. This may cause a very old
|
1241
|
+
* response to be considered valid. The +maxsec+ parameter can be used to limit
|
1242
|
+
* the age of responses.
|
1243
|
+
*/
|
1244
|
+
static VALUE
|
1245
|
+
ossl_ocspsres_check_validity(int argc, VALUE *argv, VALUE self)
|
1246
|
+
{
|
1247
|
+
OCSP_SINGLERESP *sres;
|
1248
|
+
ASN1_GENERALIZEDTIME *this_update, *next_update;
|
1249
|
+
VALUE nsec_v, maxsec_v;
|
1250
|
+
int nsec, maxsec, status, ret;
|
1251
|
+
|
1252
|
+
rb_scan_args(argc, argv, "02", &nsec_v, &maxsec_v);
|
1253
|
+
nsec = NIL_P(nsec_v) ? 0 : NUM2INT(nsec_v);
|
1254
|
+
maxsec = NIL_P(maxsec_v) ? -1 : NUM2INT(maxsec_v);
|
1255
|
+
|
1256
|
+
GetOCSPSingleRes(self, sres);
|
1257
|
+
status = OCSP_single_get0_status(sres, NULL, NULL, &this_update, &next_update);
|
1258
|
+
if (status < 0)
|
1259
|
+
ossl_raise(eOCSPError, "OCSP_single_get0_status");
|
1260
|
+
|
1261
|
+
ret = OCSP_check_validity(this_update, next_update, nsec, maxsec);
|
1262
|
+
|
1263
|
+
if (ret)
|
1264
|
+
return Qtrue;
|
1265
|
+
else {
|
1266
|
+
ossl_clear_error();
|
1267
|
+
return Qfalse;
|
1268
|
+
}
|
1269
|
+
}
|
1270
|
+
|
1271
|
+
/*
|
1272
|
+
* call-seq:
|
1273
|
+
* single_response.certid -> CertificateId
|
1274
|
+
*
|
1275
|
+
* Returns the CertificateId for which this SingleResponse is.
|
1276
|
+
*/
|
1277
|
+
static VALUE
|
1278
|
+
ossl_ocspsres_get_certid(VALUE self)
|
1279
|
+
{
|
1280
|
+
OCSP_SINGLERESP *sres;
|
1281
|
+
OCSP_CERTID *id;
|
1282
|
+
|
1283
|
+
GetOCSPSingleRes(self, sres);
|
1284
|
+
id = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(sres)); /* FIXME */
|
1285
|
+
|
1286
|
+
return ossl_ocspcertid_new(id);
|
1287
|
+
}
|
1288
|
+
|
1289
|
+
/*
|
1290
|
+
* call-seq:
|
1291
|
+
* single_response.cert_status -> Integer
|
1292
|
+
*
|
1293
|
+
* Returns the status of the certificate identified by the certid.
|
1294
|
+
* The return value may be one of these constant:
|
1295
|
+
*
|
1296
|
+
* - V_CERTSTATUS_GOOD
|
1297
|
+
* - V_CERTSTATUS_REVOKED
|
1298
|
+
* - V_CERTSTATUS_UNKNOWN
|
1299
|
+
*
|
1300
|
+
* When the status is V_CERTSTATUS_REVOKED, the time at which the certificate
|
1301
|
+
* was revoked can be retrieved by #revocation_time.
|
1302
|
+
*/
|
1303
|
+
static VALUE
|
1304
|
+
ossl_ocspsres_get_cert_status(VALUE self)
|
1305
|
+
{
|
1306
|
+
OCSP_SINGLERESP *sres;
|
1307
|
+
int status;
|
1308
|
+
|
1309
|
+
GetOCSPSingleRes(self, sres);
|
1310
|
+
status = OCSP_single_get0_status(sres, NULL, NULL, NULL, NULL);
|
1311
|
+
if (status < 0)
|
1312
|
+
ossl_raise(eOCSPError, "OCSP_single_get0_status");
|
1313
|
+
|
1314
|
+
return INT2NUM(status);
|
1315
|
+
}
|
1316
|
+
|
1317
|
+
/*
|
1318
|
+
* call-seq:
|
1319
|
+
* single_response.this_update -> Time
|
1320
|
+
*/
|
1321
|
+
static VALUE
|
1322
|
+
ossl_ocspsres_get_this_update(VALUE self)
|
1323
|
+
{
|
1324
|
+
OCSP_SINGLERESP *sres;
|
1325
|
+
int status;
|
1326
|
+
ASN1_GENERALIZEDTIME *time;
|
1327
|
+
|
1328
|
+
GetOCSPSingleRes(self, sres);
|
1329
|
+
status = OCSP_single_get0_status(sres, NULL, NULL, &time, NULL);
|
1330
|
+
if (status < 0)
|
1331
|
+
ossl_raise(eOCSPError, "OCSP_single_get0_status");
|
1332
|
+
|
1333
|
+
return asn1time_to_time(time); /* will handle NULL */
|
1334
|
+
}
|
1335
|
+
|
1336
|
+
/*
|
1337
|
+
* call-seq:
|
1338
|
+
* single_response.next_update -> Time | nil
|
1339
|
+
*/
|
1340
|
+
static VALUE
|
1341
|
+
ossl_ocspsres_get_next_update(VALUE self)
|
1342
|
+
{
|
1343
|
+
OCSP_SINGLERESP *sres;
|
1344
|
+
int status;
|
1345
|
+
ASN1_GENERALIZEDTIME *time;
|
1346
|
+
|
1347
|
+
GetOCSPSingleRes(self, sres);
|
1348
|
+
status = OCSP_single_get0_status(sres, NULL, NULL, NULL, &time);
|
1349
|
+
if (status < 0)
|
1350
|
+
ossl_raise(eOCSPError, "OCSP_single_get0_status");
|
1351
|
+
|
1352
|
+
return asn1time_to_time(time);
|
1353
|
+
}
|
1354
|
+
|
1355
|
+
/*
|
1356
|
+
* call-seq:
|
1357
|
+
* single_response.revocation_time -> Time | nil
|
1358
|
+
*/
|
1359
|
+
static VALUE
|
1360
|
+
ossl_ocspsres_get_revocation_time(VALUE self)
|
1361
|
+
{
|
1362
|
+
OCSP_SINGLERESP *sres;
|
1363
|
+
int status;
|
1364
|
+
ASN1_GENERALIZEDTIME *time;
|
1365
|
+
|
1366
|
+
GetOCSPSingleRes(self, sres);
|
1367
|
+
status = OCSP_single_get0_status(sres, NULL, &time, NULL, NULL);
|
1368
|
+
if (status < 0)
|
1369
|
+
ossl_raise(eOCSPError, "OCSP_single_get0_status");
|
1370
|
+
if (status != V_OCSP_CERTSTATUS_REVOKED)
|
1371
|
+
ossl_raise(eOCSPError, "certificate is not revoked");
|
1372
|
+
|
1373
|
+
return asn1time_to_time(time);
|
1374
|
+
}
|
1375
|
+
|
1376
|
+
/*
|
1377
|
+
* call-seq:
|
1378
|
+
* single_response.revocation_reason -> Integer | nil
|
1379
|
+
*/
|
1380
|
+
static VALUE
|
1381
|
+
ossl_ocspsres_get_revocation_reason(VALUE self)
|
1382
|
+
{
|
1383
|
+
OCSP_SINGLERESP *sres;
|
1384
|
+
int status, reason;
|
1385
|
+
|
1386
|
+
GetOCSPSingleRes(self, sres);
|
1387
|
+
status = OCSP_single_get0_status(sres, &reason, NULL, NULL, NULL);
|
1388
|
+
if (status < 0)
|
1389
|
+
ossl_raise(eOCSPError, "OCSP_single_get0_status");
|
1390
|
+
if (status != V_OCSP_CERTSTATUS_REVOKED)
|
1391
|
+
ossl_raise(eOCSPError, "certificate is not revoked");
|
1392
|
+
|
1393
|
+
return INT2NUM(reason);
|
1394
|
+
}
|
1395
|
+
|
1396
|
+
/*
|
1397
|
+
* call-seq:
|
1398
|
+
* single_response.extensions -> Array of X509::Extension
|
1399
|
+
*/
|
1400
|
+
static VALUE
|
1401
|
+
ossl_ocspsres_get_extensions(VALUE self)
|
1402
|
+
{
|
1403
|
+
OCSP_SINGLERESP *sres;
|
1404
|
+
X509_EXTENSION *ext;
|
1405
|
+
int count, i;
|
1406
|
+
VALUE ary;
|
1407
|
+
|
1408
|
+
GetOCSPSingleRes(self, sres);
|
1409
|
+
|
1410
|
+
count = OCSP_SINGLERESP_get_ext_count(sres);
|
1411
|
+
ary = rb_ary_new2(count);
|
1412
|
+
for (i = 0; i < count; i++) {
|
1413
|
+
ext = OCSP_SINGLERESP_get_ext(sres, i);
|
1414
|
+
rb_ary_push(ary, ossl_x509ext_new(ext)); /* will dup */
|
1415
|
+
}
|
1416
|
+
|
1417
|
+
return ary;
|
1418
|
+
}
|
1419
|
+
|
1420
|
+
/*
|
1421
|
+
* call-seq:
|
1422
|
+
* single_response.to_der -> String
|
1423
|
+
*
|
1424
|
+
* Encodes this SingleResponse into a DER-encoded string.
|
1425
|
+
*/
|
1426
|
+
static VALUE
|
1427
|
+
ossl_ocspsres_to_der(VALUE self)
|
1428
|
+
{
|
1429
|
+
OCSP_SINGLERESP *sres;
|
1430
|
+
VALUE str;
|
1431
|
+
long len;
|
1432
|
+
unsigned char *p;
|
1433
|
+
|
1434
|
+
GetOCSPSingleRes(self, sres);
|
1435
|
+
if ((len = i2d_OCSP_SINGLERESP(sres, NULL)) <= 0)
|
1436
|
+
ossl_raise(eOCSPError, NULL);
|
1437
|
+
str = rb_str_new(0, len);
|
1438
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
1439
|
+
if (i2d_OCSP_SINGLERESP(sres, &p) <= 0)
|
1440
|
+
ossl_raise(eOCSPError, NULL);
|
1441
|
+
ossl_str_adjust(str, p);
|
1442
|
+
|
1443
|
+
return str;
|
1444
|
+
}
|
1445
|
+
|
1446
|
+
|
863
1447
|
/*
|
864
1448
|
* OCSP::CertificateId
|
865
1449
|
*/
|
@@ -877,41 +1461,71 @@ ossl_ocspcid_alloc(VALUE klass)
|
|
877
1461
|
return obj;
|
878
1462
|
}
|
879
1463
|
|
1464
|
+
static VALUE
|
1465
|
+
ossl_ocspcid_initialize_copy(VALUE self, VALUE other)
|
1466
|
+
{
|
1467
|
+
OCSP_CERTID *cid, *cid_old, *cid_new;
|
1468
|
+
|
1469
|
+
rb_check_frozen(self);
|
1470
|
+
GetOCSPCertId(self, cid_old);
|
1471
|
+
SafeGetOCSPCertId(other, cid);
|
1472
|
+
|
1473
|
+
cid_new = OCSP_CERTID_dup(cid);
|
1474
|
+
if (!cid_new)
|
1475
|
+
ossl_raise(eOCSPError, "OCSP_CERTID_dup");
|
1476
|
+
|
1477
|
+
SetOCSPCertId(self, cid_new);
|
1478
|
+
OCSP_CERTID_free(cid_old);
|
1479
|
+
|
1480
|
+
return self;
|
1481
|
+
}
|
1482
|
+
|
880
1483
|
/*
|
881
1484
|
* call-seq:
|
882
1485
|
* OpenSSL::OCSP::CertificateId.new(subject, issuer, digest = nil) -> certificate_id
|
1486
|
+
* OpenSSL::OCSP::CertificateId.new(der_string) -> certificate_id
|
883
1487
|
*
|
884
1488
|
* Creates a new OpenSSL::OCSP::CertificateId for the given +subject+ and
|
885
1489
|
* +issuer+ X509 certificates. The +digest+ is used to compute the
|
886
1490
|
* certificate ID and must be an OpenSSL::Digest instance.
|
1491
|
+
*
|
1492
|
+
* If only one argument is given, decodes it as DER representation of a
|
1493
|
+
* certificate ID.
|
887
1494
|
*/
|
888
1495
|
|
889
1496
|
static VALUE
|
890
1497
|
ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
|
891
1498
|
{
|
892
1499
|
OCSP_CERTID *id, *newid;
|
893
|
-
X509 *x509s, *x509i;
|
894
1500
|
VALUE subject, issuer, digest;
|
895
|
-
const EVP_MD *md;
|
896
1501
|
|
897
|
-
|
898
|
-
|
1502
|
+
GetOCSPCertId(self, id);
|
1503
|
+
if (rb_scan_args(argc, argv, "12", &subject, &issuer, &digest) == 1) {
|
1504
|
+
VALUE arg;
|
1505
|
+
const unsigned char *p;
|
1506
|
+
|
1507
|
+
arg = ossl_to_der_if_possible(subject);
|
1508
|
+
StringValue(arg);
|
1509
|
+
p = (unsigned char *)RSTRING_PTR(arg);
|
1510
|
+
newid = d2i_OCSP_CERTID(NULL, &p, RSTRING_LEN(arg));
|
1511
|
+
if (!newid)
|
1512
|
+
ossl_raise(eOCSPError, "d2i_OCSP_CERTID");
|
899
1513
|
}
|
1514
|
+
else {
|
1515
|
+
X509 *x509s, *x509i;
|
1516
|
+
const EVP_MD *md;
|
900
1517
|
|
901
|
-
|
902
|
-
|
1518
|
+
x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */
|
1519
|
+
x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */
|
1520
|
+
md = !NIL_P(digest) ? GetDigestPtr(digest) : NULL;
|
903
1521
|
|
904
|
-
if (!NIL_P(digest)) {
|
905
|
-
md = GetDigestPtr(digest);
|
906
1522
|
newid = OCSP_cert_to_id(md, x509s, x509i);
|
907
|
-
|
908
|
-
|
1523
|
+
if (!newid)
|
1524
|
+
ossl_raise(eOCSPError, "OCSP_cert_to_id");
|
909
1525
|
}
|
910
|
-
|
911
|
-
|
912
|
-
GetOCSPCertId(self, id);
|
1526
|
+
|
1527
|
+
SetOCSPCertId(self, newid);
|
913
1528
|
OCSP_CERTID_free(id);
|
914
|
-
RDATA(self)->data = newid;
|
915
1529
|
|
916
1530
|
return self;
|
917
1531
|
}
|
@@ -959,24 +1573,130 @@ ossl_ocspcid_cmp_issuer(VALUE self, VALUE other)
|
|
959
1573
|
|
960
1574
|
/*
|
961
1575
|
* call-seq:
|
962
|
-
* certificate_id.
|
1576
|
+
* certificate_id.serial -> Integer
|
963
1577
|
*
|
964
|
-
* Returns the serial number of the
|
1578
|
+
* Returns the serial number of the certificate for which status is being
|
1579
|
+
* requested.
|
965
1580
|
*/
|
966
|
-
|
967
1581
|
static VALUE
|
968
1582
|
ossl_ocspcid_get_serial(VALUE self)
|
969
1583
|
{
|
970
1584
|
OCSP_CERTID *id;
|
1585
|
+
ASN1_INTEGER *serial;
|
1586
|
+
|
1587
|
+
GetOCSPCertId(self, id);
|
1588
|
+
OCSP_id_get0_info(NULL, NULL, NULL, &serial, id);
|
1589
|
+
|
1590
|
+
return asn1integer_to_num(serial);
|
1591
|
+
}
|
1592
|
+
|
1593
|
+
/*
|
1594
|
+
* call-seq:
|
1595
|
+
* certificate_id.issuer_name_hash -> String
|
1596
|
+
*
|
1597
|
+
* Returns the issuerNameHash of this certificate ID, the hash of the
|
1598
|
+
* issuer's distinguished name calculated with the hashAlgorithm.
|
1599
|
+
*/
|
1600
|
+
static VALUE
|
1601
|
+
ossl_ocspcid_get_issuer_name_hash(VALUE self)
|
1602
|
+
{
|
1603
|
+
OCSP_CERTID *id;
|
1604
|
+
ASN1_OCTET_STRING *name_hash;
|
1605
|
+
VALUE ret;
|
971
1606
|
|
972
1607
|
GetOCSPCertId(self, id);
|
1608
|
+
OCSP_id_get0_info(&name_hash, NULL, NULL, NULL, id);
|
1609
|
+
|
1610
|
+
ret = rb_str_new(NULL, name_hash->length * 2);
|
1611
|
+
ossl_bin2hex(name_hash->data, RSTRING_PTR(ret), name_hash->length);
|
973
1612
|
|
974
|
-
return
|
1613
|
+
return ret;
|
1614
|
+
}
|
1615
|
+
|
1616
|
+
/*
|
1617
|
+
* call-seq:
|
1618
|
+
* certificate_id.issuer_key_hash -> String
|
1619
|
+
*
|
1620
|
+
* Returns the issuerKeyHash of this certificate ID, the hash of the issuer's
|
1621
|
+
* public key.
|
1622
|
+
*/
|
1623
|
+
static VALUE
|
1624
|
+
ossl_ocspcid_get_issuer_key_hash(VALUE self)
|
1625
|
+
{
|
1626
|
+
OCSP_CERTID *id;
|
1627
|
+
ASN1_OCTET_STRING *key_hash;
|
1628
|
+
VALUE ret;
|
1629
|
+
|
1630
|
+
GetOCSPCertId(self, id);
|
1631
|
+
OCSP_id_get0_info(NULL, NULL, &key_hash, NULL, id);
|
1632
|
+
|
1633
|
+
ret = rb_str_new(NULL, key_hash->length * 2);
|
1634
|
+
ossl_bin2hex(key_hash->data, RSTRING_PTR(ret), key_hash->length);
|
1635
|
+
|
1636
|
+
return ret;
|
1637
|
+
}
|
1638
|
+
|
1639
|
+
/*
|
1640
|
+
* call-seq:
|
1641
|
+
* certificate_id.hash_algorithm -> String
|
1642
|
+
*
|
1643
|
+
* Returns the ln (long name) of the hash algorithm used to generate
|
1644
|
+
* the issuerNameHash and the issuerKeyHash values.
|
1645
|
+
*/
|
1646
|
+
static VALUE
|
1647
|
+
ossl_ocspcid_get_hash_algorithm(VALUE self)
|
1648
|
+
{
|
1649
|
+
OCSP_CERTID *id;
|
1650
|
+
ASN1_OBJECT *oid;
|
1651
|
+
BIO *out;
|
1652
|
+
|
1653
|
+
GetOCSPCertId(self, id);
|
1654
|
+
OCSP_id_get0_info(NULL, &oid, NULL, NULL, id);
|
1655
|
+
|
1656
|
+
if (!(out = BIO_new(BIO_s_mem())))
|
1657
|
+
ossl_raise(eOCSPError, "BIO_new");
|
1658
|
+
|
1659
|
+
if (!i2a_ASN1_OBJECT(out, oid)) {
|
1660
|
+
BIO_free(out);
|
1661
|
+
ossl_raise(eOCSPError, "i2a_ASN1_OBJECT");
|
1662
|
+
}
|
1663
|
+
return ossl_membio2str(out);
|
1664
|
+
}
|
1665
|
+
|
1666
|
+
/*
|
1667
|
+
* call-seq:
|
1668
|
+
* certificate_id.to_der -> String
|
1669
|
+
*
|
1670
|
+
* Encodes this certificate identifier into a DER-encoded string.
|
1671
|
+
*/
|
1672
|
+
static VALUE
|
1673
|
+
ossl_ocspcid_to_der(VALUE self)
|
1674
|
+
{
|
1675
|
+
OCSP_CERTID *id;
|
1676
|
+
VALUE str;
|
1677
|
+
long len;
|
1678
|
+
unsigned char *p;
|
1679
|
+
|
1680
|
+
GetOCSPCertId(self, id);
|
1681
|
+
if ((len = i2d_OCSP_CERTID(id, NULL)) <= 0)
|
1682
|
+
ossl_raise(eOCSPError, NULL);
|
1683
|
+
str = rb_str_new(0, len);
|
1684
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
1685
|
+
if (i2d_OCSP_CERTID(id, &p) <= 0)
|
1686
|
+
ossl_raise(eOCSPError, NULL);
|
1687
|
+
ossl_str_adjust(str, p);
|
1688
|
+
|
1689
|
+
return str;
|
975
1690
|
}
|
976
1691
|
|
977
1692
|
void
|
978
1693
|
Init_ossl_ocsp(void)
|
979
1694
|
{
|
1695
|
+
#if 0
|
1696
|
+
mOSSL = rb_define_module("OpenSSL");
|
1697
|
+
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
1698
|
+
#endif
|
1699
|
+
|
980
1700
|
/*
|
981
1701
|
* OpenSSL::OCSP implements Online Certificate Status Protocol requests
|
982
1702
|
* and responses.
|
@@ -1046,7 +1766,7 @@ Init_ossl_ocsp(void)
|
|
1046
1766
|
* store = OpenSSL::X509::Store.new
|
1047
1767
|
* store.set_default_paths
|
1048
1768
|
*
|
1049
|
-
* unless
|
1769
|
+
* unless response_basic.verify [], store then
|
1050
1770
|
* raise 'response is not signed by a trusted certificate'
|
1051
1771
|
* end
|
1052
1772
|
*
|
@@ -1062,27 +1782,28 @@ Init_ossl_ocsp(void)
|
|
1062
1782
|
*
|
1063
1783
|
* p request.check_nonce basic_response #=> value from -1 to 3
|
1064
1784
|
*
|
1065
|
-
* Then extract the status information from the basic
|
1066
|
-
*
|
1067
|
-
* submitted one.)
|
1068
|
-
*
|
1069
|
-
* response_certificate_id, status, reason, revocation_time,
|
1070
|
-
* this_update, next_update, extensions = basic_response.status
|
1785
|
+
* Then extract the status information for the certificate from the basic
|
1786
|
+
* response.
|
1071
1787
|
*
|
1072
|
-
*
|
1788
|
+
* single_response = basic_response.find_response(certificate_id)
|
1073
1789
|
*
|
1074
|
-
* unless
|
1075
|
-
* raise '
|
1790
|
+
* unless single_response
|
1791
|
+
* raise 'basic_response does not have the status for the certificiate'
|
1076
1792
|
* end
|
1077
1793
|
*
|
1078
|
-
*
|
1794
|
+
* Then check the validity. A status issued in the future must be rejected.
|
1079
1795
|
*
|
1080
|
-
*
|
1081
|
-
* raise '
|
1796
|
+
* unless single_response.check_validity
|
1797
|
+
* raise 'this_update is in the future or next_update time has passed'
|
1082
1798
|
* end
|
1083
1799
|
*
|
1084
|
-
*
|
1085
|
-
*
|
1800
|
+
* case single_response.cert_status
|
1801
|
+
* when OpenSSL::OCSP::V_CERTSTATUS_GOOD
|
1802
|
+
* puts 'certificate is still valid'
|
1803
|
+
* when OpenSSL::OCSP::V_CERTSTATUS_REVOKED
|
1804
|
+
* puts "certificate has been revoked at #{single_response.revocation_time}"
|
1805
|
+
* when OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
|
1806
|
+
* puts 'responder doesn't know about the certificate'
|
1086
1807
|
* end
|
1087
1808
|
*/
|
1088
1809
|
|
@@ -1103,6 +1824,7 @@ Init_ossl_ocsp(void)
|
|
1103
1824
|
|
1104
1825
|
cOCSPReq = rb_define_class_under(mOCSP, "Request", rb_cObject);
|
1105
1826
|
rb_define_alloc_func(cOCSPReq, ossl_ocspreq_alloc);
|
1827
|
+
rb_define_copy_func(cOCSPReq, ossl_ocspreq_initialize_copy);
|
1106
1828
|
rb_define_method(cOCSPReq, "initialize", ossl_ocspreq_initialize, -1);
|
1107
1829
|
rb_define_method(cOCSPReq, "add_nonce", ossl_ocspreq_add_nonce, -1);
|
1108
1830
|
rb_define_method(cOCSPReq, "check_nonce", ossl_ocspreq_check_nonce, 1);
|
@@ -1120,6 +1842,7 @@ Init_ossl_ocsp(void)
|
|
1120
1842
|
cOCSPRes = rb_define_class_under(mOCSP, "Response", rb_cObject);
|
1121
1843
|
rb_define_singleton_method(cOCSPRes, "create", ossl_ocspres_s_create, 2);
|
1122
1844
|
rb_define_alloc_func(cOCSPRes, ossl_ocspres_alloc);
|
1845
|
+
rb_define_copy_func(cOCSPRes, ossl_ocspres_initialize_copy);
|
1123
1846
|
rb_define_method(cOCSPRes, "initialize", ossl_ocspres_initialize, -1);
|
1124
1847
|
rb_define_method(cOCSPRes, "status", ossl_ocspres_status, 0);
|
1125
1848
|
rb_define_method(cOCSPRes, "status_string", ossl_ocspres_status_string, 0);
|
@@ -1134,13 +1857,36 @@ Init_ossl_ocsp(void)
|
|
1134
1857
|
|
1135
1858
|
cOCSPBasicRes = rb_define_class_under(mOCSP, "BasicResponse", rb_cObject);
|
1136
1859
|
rb_define_alloc_func(cOCSPBasicRes, ossl_ocspbres_alloc);
|
1860
|
+
rb_define_copy_func(cOCSPBasicRes, ossl_ocspbres_initialize_copy);
|
1137
1861
|
rb_define_method(cOCSPBasicRes, "initialize", ossl_ocspbres_initialize, -1);
|
1138
1862
|
rb_define_method(cOCSPBasicRes, "copy_nonce", ossl_ocspbres_copy_nonce, 1);
|
1139
1863
|
rb_define_method(cOCSPBasicRes, "add_nonce", ossl_ocspbres_add_nonce, -1);
|
1140
1864
|
rb_define_method(cOCSPBasicRes, "add_status", ossl_ocspbres_add_status, 7);
|
1141
1865
|
rb_define_method(cOCSPBasicRes, "status", ossl_ocspbres_get_status, 0);
|
1866
|
+
rb_define_method(cOCSPBasicRes, "responses", ossl_ocspbres_get_responses, 0);
|
1867
|
+
rb_define_method(cOCSPBasicRes, "find_response", ossl_ocspbres_find_response, 1);
|
1142
1868
|
rb_define_method(cOCSPBasicRes, "sign", ossl_ocspbres_sign, -1);
|
1143
1869
|
rb_define_method(cOCSPBasicRes, "verify", ossl_ocspbres_verify, -1);
|
1870
|
+
rb_define_method(cOCSPBasicRes, "to_der", ossl_ocspbres_to_der, 0);
|
1871
|
+
|
1872
|
+
/*
|
1873
|
+
* An OpenSSL::OCSP::SingleResponse represents an OCSP SingleResponse
|
1874
|
+
* structure, which contains the basic information of the status of the
|
1875
|
+
* certificate.
|
1876
|
+
*/
|
1877
|
+
cOCSPSingleRes = rb_define_class_under(mOCSP, "SingleResponse", rb_cObject);
|
1878
|
+
rb_define_alloc_func(cOCSPSingleRes, ossl_ocspsres_alloc);
|
1879
|
+
rb_define_copy_func(cOCSPSingleRes, ossl_ocspsres_initialize_copy);
|
1880
|
+
rb_define_method(cOCSPSingleRes, "initialize", ossl_ocspsres_initialize, 1);
|
1881
|
+
rb_define_method(cOCSPSingleRes, "check_validity", ossl_ocspsres_check_validity, -1);
|
1882
|
+
rb_define_method(cOCSPSingleRes, "certid", ossl_ocspsres_get_certid, 0);
|
1883
|
+
rb_define_method(cOCSPSingleRes, "cert_status", ossl_ocspsres_get_cert_status, 0);
|
1884
|
+
rb_define_method(cOCSPSingleRes, "this_update", ossl_ocspsres_get_this_update, 0);
|
1885
|
+
rb_define_method(cOCSPSingleRes, "next_update", ossl_ocspsres_get_next_update, 0);
|
1886
|
+
rb_define_method(cOCSPSingleRes, "revocation_time", ossl_ocspsres_get_revocation_time, 0);
|
1887
|
+
rb_define_method(cOCSPSingleRes, "revocation_reason", ossl_ocspsres_get_revocation_reason, 0);
|
1888
|
+
rb_define_method(cOCSPSingleRes, "extensions", ossl_ocspsres_get_extensions, 0);
|
1889
|
+
rb_define_method(cOCSPSingleRes, "to_der", ossl_ocspsres_to_der, 0);
|
1144
1890
|
|
1145
1891
|
/*
|
1146
1892
|
* An OpenSSL::OCSP::CertificateId identifies a certificate to the CA so
|
@@ -1149,10 +1895,15 @@ Init_ossl_ocsp(void)
|
|
1149
1895
|
|
1150
1896
|
cOCSPCertId = rb_define_class_under(mOCSP, "CertificateId", rb_cObject);
|
1151
1897
|
rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc);
|
1898
|
+
rb_define_copy_func(cOCSPCertId, ossl_ocspcid_initialize_copy);
|
1152
1899
|
rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize, -1);
|
1153
1900
|
rb_define_method(cOCSPCertId, "cmp", ossl_ocspcid_cmp, 1);
|
1154
1901
|
rb_define_method(cOCSPCertId, "cmp_issuer", ossl_ocspcid_cmp_issuer, 1);
|
1155
1902
|
rb_define_method(cOCSPCertId, "serial", ossl_ocspcid_get_serial, 0);
|
1903
|
+
rb_define_method(cOCSPCertId, "issuer_name_hash", ossl_ocspcid_get_issuer_name_hash, 0);
|
1904
|
+
rb_define_method(cOCSPCertId, "issuer_key_hash", ossl_ocspcid_get_issuer_key_hash, 0);
|
1905
|
+
rb_define_method(cOCSPCertId, "hash_algorithm", ossl_ocspcid_get_hash_algorithm, 0);
|
1906
|
+
rb_define_method(cOCSPCertId, "to_der", ossl_ocspcid_to_der, 0);
|
1156
1907
|
|
1157
1908
|
/* Internal error in issuer */
|
1158
1909
|
rb_define_const(mOCSP, "RESPONSE_STATUS_INTERNALERROR", INT2NUM(OCSP_RESPONSE_STATUS_INTERNALERROR));
|
@@ -1254,8 +2005,7 @@ Init_ossl_ocsp(void)
|
|
1254
2005
|
/* The responder ID is based on the public key. */
|
1255
2006
|
rb_define_const(mOCSP, "V_RESPID_KEY", INT2NUM(V_OCSP_RESPID_KEY));
|
1256
2007
|
}
|
1257
|
-
|
1258
|
-
#else /* ! OSSL_OCSP_ENABLED */
|
2008
|
+
#else
|
1259
2009
|
void
|
1260
2010
|
Init_ossl_ocsp(void)
|
1261
2011
|
{
|