summaryrefslogtreecommitdiff
path: root/ext/openssl/ossl_ocsp.c
diff options
context:
space:
mode:
authorrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-08-29 05:47:09 +0000
committerrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-08-29 05:47:09 +0000
commitc9dc0164b8ad1cb23faf6120749bcc349a7bfd45 (patch)
tree831281099f54c0be80293785761a46688a0711f3 /ext/openssl/ossl_ocsp.c
parent28bf4d545fb7674fcdc99c93ba7476d320551d11 (diff)
import Ruby/OpenSSL 2.0.0.beta.1
* NEWS, {ext,test,sample}/openssl: Import Ruby/OpenSSL 2.0.0.beta.1. ext/openssl is now converted into a default gem. The full commit history since r55538 can be found at: https://github.com/ruby/openssl/compare/08e1881f5663...v2.0.0.beta.1 [Feature #9612] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl/ossl_ocsp.c')
-rw-r--r--ext/openssl/ossl_ocsp.c108
1 files changed, 83 insertions, 25 deletions
diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c
index c0f2dfefb3..a8b3503d2a 100644
--- a/ext/openssl/ossl_ocsp.c
+++ b/ext/openssl/ossl_ocsp.c
@@ -321,12 +321,17 @@ static VALUE
ossl_ocspreq_add_certid(VALUE self, VALUE certid)
{
OCSP_REQUEST *req;
- OCSP_CERTID *id;
+ OCSP_CERTID *id, *id_new;
GetOCSPReq(self, req);
GetOCSPCertId(certid, id);
- if(!OCSP_request_add0_id(req, OCSP_CERTID_dup(id)))
- ossl_raise(eOCSPError, NULL);
+
+ if (!(id_new = OCSP_CERTID_dup(id)))
+ ossl_raise(eOCSPError, "OCSP_CERTID_dup");
+ if (!OCSP_request_add0_id(req, id_new)) {
+ OCSP_CERTID_free(id_new);
+ ossl_raise(eOCSPError, "OCSP_request_add0_id");
+ }
return self;
}
@@ -368,14 +373,16 @@ ossl_ocspreq_get_certid(VALUE self)
*
* Signs this OCSP request using +cert+, +key+ and optional +digest+. If
* +digest+ is not specified, SHA-1 is used. +certs+ is an optional Array of
- * additional certificates that will be included in the request. If +certs+ is
- * not specified, flag OpenSSL::OCSP::NOCERTS is set. Pass an empty array to
- * include only the signer certificate.
+ * additional certificates which are included in the request in addition to
+ * the signer certificate. Note that if +certs+ is nil or not given, flag
+ * OpenSSL::OCSP::NOCERTS is enabled. Pass an empty array to include only the
+ * signer certificate.
*
- * +flags+ can include:
- * OpenSSL::OCSP::NOCERTS:: don't include certificates
+ * +flags+ can be a bitwise OR of the following constants:
+ *
+ * OpenSSL::OCSP::NOCERTS::
+ * Don't include any certificates in the request. +certs+ will be ignored.
*/
-
static VALUE
ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
{
@@ -399,7 +406,7 @@ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
else
md = GetDigestPtr(digest);
if (NIL_P(certs))
- flags |= OCSP_NOCERTS;
+ flg |= OCSP_NOCERTS;
else
x509s = ossl_x509_ary2sk(certs);
@@ -435,7 +442,7 @@ ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)
x509s = ossl_x509_ary2sk(certs);
result = OCSP_request_verify(req, x509s, x509st, flg);
sk_X509_pop_free(x509s, X509_free);
- if (!result)
+ if (result <= 0)
ossl_clear_error();
return result > 0 ? Qtrue : Qfalse;
@@ -856,13 +863,11 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
X509_EXTENSION *x509ext;
for(i = 0; i < RARRAY_LEN(ext); i++){
- x509ext = DupX509ExtPtr(RARRAY_AREF(ext, i));
+ x509ext = GetX509ExtPtr(RARRAY_AREF(ext, i));
if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
- X509_EXTENSION_free(x509ext);
error = 1;
goto err;
}
- X509_EXTENSION_free(x509ext);
}
}
@@ -911,7 +916,7 @@ ossl_ocspbres_get_status(VALUE self)
status = OCSP_single_get0_status(single, &reason, &revtime,
&thisupd, &nextupd);
if(status < 0) continue;
- if(!(cid = OCSP_CERTID_dup(OCSP_SINGLERESP_get0_id(single))))
+ if(!(cid = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(single)))) /* FIXME */
ossl_raise(eOCSPError, NULL);
ary = rb_ary_new();
rb_ary_push(ary, ossl_ocspcertid_new(cid));
@@ -1065,9 +1070,57 @@ ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
x509st = GetX509StorePtr(store);
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
x509s = ossl_x509_ary2sk(certs);
+#if (OPENSSL_VERSION_NUMBER < 0x1000202fL) || defined(LIBRESSL_VERSION_NUMBER)
+ /*
+ * OpenSSL had a bug that it doesn't use the certificates in x509s for
+ * verifying the chain. This can be a problem when the response is signed by
+ * a certificate issued by an intermediate CA.
+ *
+ * root_ca
+ * |
+ * intermediate_ca
+ * |-------------|
+ * end_entity ocsp_signer
+ *
+ * When the certificate hierarchy is like this, and the response contains
+ * only ocsp_signer certificate, the following code wrongly fails.
+ *
+ * store = OpenSSL::X509::Store.new; store.add_cert(root_ca)
+ * basic_response.verify([intermediate_ca], store)
+ *
+ * So add the certificates in x509s to the embedded certificates list first.
+ *
+ * This is fixed in OpenSSL 0.9.8zg, 1.0.0s, 1.0.1n, 1.0.2b. But it still
+ * exists in LibreSSL 2.1.10, 2.2.9, 2.3.6, 2.4.1.
+ */
+ if (!(flg & (OCSP_NOCHAIN | OCSP_NOVERIFY)) &&
+ sk_X509_num(x509s) && sk_X509_num(bs->certs)) {
+ int i;
+
+ bs = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
+ if (!bs) {
+ sk_X509_pop_free(x509s, X509_free);
+ ossl_raise(eOCSPError, "ASN1_item_dup");
+ }
+
+ for (i = 0; i < sk_X509_num(x509s); i++) {
+ if (!OCSP_basic_add1_cert(bs, sk_X509_value(x509s, i))) {
+ sk_X509_pop_free(x509s, X509_free);
+ OCSP_BASICRESP_free(bs);
+ ossl_raise(eOCSPError, "OCSP_basic_add1_cert");
+ }
+ }
+ result = OCSP_basic_verify(bs, x509s, x509st, flg);
+ OCSP_BASICRESP_free(bs);
+ }
+ else {
+ result = OCSP_basic_verify(bs, x509s, x509st, flg);
+ }
+#else
result = OCSP_basic_verify(bs, x509s, x509st, flg);
+#endif
sk_X509_pop_free(x509s, X509_free);
- if (!result)
+ if (result <= 0)
ossl_clear_error();
return result > 0 ? Qtrue : Qfalse;
@@ -1228,7 +1281,7 @@ ossl_ocspsres_get_certid(VALUE self)
OCSP_CERTID *id;
GetOCSPSingleRes(self, sres);
- id = OCSP_CERTID_dup(OCSP_SINGLERESP_get0_id(sres));
+ id = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(sres)); /* FIXME */
return ossl_ocspcertid_new(id);
}
@@ -1549,15 +1602,15 @@ ossl_ocspcid_get_issuer_name_hash(VALUE self)
{
OCSP_CERTID *id;
ASN1_OCTET_STRING *name_hash;
- char *hexbuf;
+ VALUE ret;
GetOCSPCertId(self, id);
OCSP_id_get0_info(&name_hash, NULL, NULL, NULL, id);
- if (string2hex(name_hash->data, name_hash->length, &hexbuf, NULL) < 0)
- ossl_raise(eOCSPError, "string2hex");
+ ret = rb_str_new(NULL, name_hash->length * 2);
+ ossl_bin2hex(name_hash->data, RSTRING_PTR(ret), name_hash->length);
- return ossl_buf2str(hexbuf, name_hash->length * 2);
+ return ret;
}
/*
@@ -1572,15 +1625,15 @@ ossl_ocspcid_get_issuer_key_hash(VALUE self)
{
OCSP_CERTID *id;
ASN1_OCTET_STRING *key_hash;
- char *hexbuf;
+ VALUE ret;
GetOCSPCertId(self, id);
OCSP_id_get0_info(NULL, NULL, &key_hash, NULL, id);
- if (string2hex(key_hash->data, key_hash->length, &hexbuf, NULL) < 0)
- ossl_raise(eOCSPError, "string2hex");
+ ret = rb_str_new(NULL, key_hash->length * 2);
+ ossl_bin2hex(key_hash->data, RSTRING_PTR(ret), key_hash->length);
- return ossl_buf2str(hexbuf, key_hash->length * 2);
+ return ret;
}
/*
@@ -1639,6 +1692,11 @@ ossl_ocspcid_to_der(VALUE self)
void
Init_ossl_ocsp(void)
{
+#if 0
+ mOSSL = rb_define_module("OpenSSL");
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
+#endif
+
/*
* OpenSSL::OCSP implements Online Certificate Status Protocol requests
* and responses.