Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ext/openssl/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ def find_openssl_library
have_func("TS_RESP_CTX_set_time_cb(NULL, NULL, NULL)", ts_h)
have_func("EVP_PBE_scrypt(\"\", 0, (unsigned char *)\"\", 0, 0, 0, 0, 0, NULL, 0)", evp_h)
have_func("SSL_CTX_set_post_handshake_auth(NULL, 0)", ssl_h)
have_func("ASN1_STRING_get0_data(NULL)", "openssl/asn1.h")

# added in 1.1.1
have_func("EVP_PKEY_check(NULL)", evp_h)
Expand All @@ -203,6 +204,9 @@ def find_openssl_library
have_func("EVP_PKEY_eq(NULL, NULL)", evp_h)
have_func("EVP_PKEY_dup(NULL)", evp_h)

# added in 4.0.0
have_func("ASN1_BIT_STRING_set1(NULL, NULL, 0, 0)", "openssl/asn1.h")

Logging::message "=== Checking done. ===\n"

# Append flags from environment variables.
Expand Down
1 change: 1 addition & 0 deletions ext/openssl/openssl_missing.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* (See the file 'LICENCE'.)
*/
#include RUBY_EXTCONF_H
#include <ruby.h>

#include <string.h> /* memcpy() */
#include <openssl/x509_vfy.h>
Expand Down
27 changes: 27 additions & 0 deletions ext/openssl/openssl_missing.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
} while (0)
#endif

#if !defined(HAVE_ASN1_STRING_GET0_DATA)
# define ASN1_STRING_get0_data(x) ((x)->data)
#endif

/* added in 3.0.0 */
#if !defined(HAVE_TS_VERIFY_CTX_SET_CERTS)
# define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts)
Expand All @@ -235,4 +239,27 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
# define EVP_PKEY_eq(a, b) EVP_PKEY_cmp(a, b)
#endif

/* added in 4.0.0 */
#ifndef HAVE_ASN1_BIT_STRING_SET1
static inline int
ASN1_BIT_STRING_set1(ASN1_BIT_STRING *bitstr, const uint8_t *data,
size_t length, int unused_bits)
{
if (length > INT_MAX || !ASN1_STRING_set(bitstr, data, (int)length))
return 0;
bitstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
bitstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
return 1;
}

static inline int
ASN1_BIT_STRING_get_length(const ASN1_BIT_STRING *bitstr, size_t *length,
int *unused_bits)
{
*length = bitstr->length;
*unused_bits = bitstr->flags & 0x07;
return 1;
}
#endif

#endif /* _OSSL_OPENSSL_MISSING_H_ */
2 changes: 1 addition & 1 deletion ext/openssl/ossl.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ ossl_buf2str(char *buf, int len)
}

void
ossl_bin2hex(unsigned char *in, char *out, size_t inlen)
ossl_bin2hex(const unsigned char *in, char *out, size_t inlen)
{
const char *hex = "0123456789abcdef";
size_t i;
Expand Down
3 changes: 2 additions & 1 deletion ext/openssl/ossl.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@

#if OSSL_OPENSSL_PREREQ(3, 0, 0)
# define OSSL_USE_PROVIDER
# include <openssl/provider.h>
#endif

/*
Expand Down Expand Up @@ -119,7 +120,7 @@ do{\
* Convert binary string to hex string. The caller is responsible for
* ensuring out has (2 * len) bytes of capacity.
*/
void ossl_bin2hex(unsigned char *in, char *out, size_t len);
void ossl_bin2hex(const unsigned char *in, char *out, size_t len);

/*
* Our default PEM callback
Expand Down
81 changes: 43 additions & 38 deletions ext/openssl/ossl_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,26 @@ static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
* DATE conversion
*/
VALUE
asn1time_to_time(const ASN1_TIME *time)
asn1time_to_time(const ASN1_TIME *time_)
{
ASN1_TIME *time = (ASN1_TIME *)time_; // const cast for OpenSSL 1.0.2
struct tm tm;
VALUE argv[6];
int count;

memset(&tm, 0, sizeof(struct tm));

switch (time->type) {
switch (ASN1_STRING_type(time)) {
case V_ASN1_UTCTIME:
count = sscanf((const char *)time->data, "%2d%2d%2d%2d%2d%2dZ",
count = sscanf((const char *)ASN1_STRING_get0_data(time), "%2d%2d%2d%2d%2d%2dZ",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
&tm.tm_sec);

if (count == 5) {
tm.tm_sec = 0;
} else if (count != 6) {
ossl_raise(rb_eTypeError, "bad UTCTIME format: \"%s\"",
time->data);
ASN1_STRING_get0_data(time));
}
if (tm.tm_year < 69) {
tm.tm_year += 2000;
Expand All @@ -44,15 +45,15 @@ asn1time_to_time(const ASN1_TIME *time)
}
break;
case V_ASN1_GENERALIZEDTIME:
count = sscanf((const char *)time->data, "%4d%2d%2d%2d%2d%2dZ",
count = sscanf((const char *)ASN1_STRING_get0_data(time), "%4d%2d%2d%2d%2d%2dZ",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
&tm.tm_sec);
if (count == 5) {
tm.tm_sec = 0;
}
else if (count != 6) {
ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format: \"%s\"",
time->data);
ASN1_STRING_get0_data(time));
}
break;
default:
Expand Down Expand Up @@ -97,7 +98,8 @@ ossl_time_split(VALUE time, time_t *sec, int *days)
VALUE
asn1str_to_str(const ASN1_STRING *str)
{
return rb_str_new((const char *)str->data, str->length);
return rb_str_new((const char *)ASN1_STRING_get0_data(str),
ASN1_STRING_length(str));
}

/*
Expand All @@ -112,9 +114,9 @@ asn1integer_to_num(const ASN1_INTEGER *ai)
if (!ai) {
ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!");
}
if (ai->type == V_ASN1_ENUMERATED)
/* const_cast: workaround for old OpenSSL */
bn = ASN1_ENUMERATED_to_BN((ASN1_ENUMERATED *)ai, NULL);
if (ASN1_STRING_type((ASN1_STRING *)ai) == V_ASN1_ENUMERATED)
/* const_cast: workaround for old OpenSSL */
bn = ASN1_ENUMERATED_to_BN((ASN1_ENUMERATED *)ai, NULL);
else
bn = ASN1_INTEGER_to_BN(ai, NULL);

Expand Down Expand Up @@ -210,19 +212,19 @@ obj_to_asn1int(VALUE obj)
}

static ASN1_BIT_STRING*
obj_to_asn1bstr(VALUE obj, long unused_bits)
obj_to_asn1bstr(VALUE obj, int unused_bits)
{
ASN1_BIT_STRING *bstr;

if (unused_bits < 0 || unused_bits > 7)
ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\
"the range 0 to 7");
StringValue(obj);
if(!(bstr = ASN1_BIT_STRING_new()))
ossl_raise(eASN1Error, NULL);
ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj));
bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
if (!(bstr = ASN1_BIT_STRING_new()))
ossl_raise(eASN1Error, "ASN1_BIT_STRING_new");
if (!ASN1_BIT_STRING_set1(bstr, (uint8_t *)RSTRING_PTR(obj),
RSTRING_LEN(obj), unused_bits))
ossl_raise(eASN1Error, "ASN1_BIT_STRING_set1");

return bstr;
}
Expand Down Expand Up @@ -346,22 +348,25 @@ decode_int(unsigned char* der, long length)
}

static VALUE
decode_bstr(unsigned char* der, long length, long *unused_bits)
decode_bstr(unsigned char* der, long length, int *unused_bits)
{
ASN1_BIT_STRING *bstr;
const unsigned char *p;
long len;
size_t len;
VALUE ret;
int state;

p = der;
if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
ossl_raise(eASN1Error, NULL);
len = bstr->length;
*unused_bits = 0;
if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
*unused_bits = bstr->flags & 0x07;
ret = rb_str_new((const char *)bstr->data, len);
if (!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
ossl_raise(eASN1Error, "d2i_ASN1_BIT_STRING");
if (!ASN1_BIT_STRING_get_length(bstr, &len, unused_bits)) {
ASN1_BIT_STRING_free(bstr);
ossl_raise(eASN1Error, "ASN1_BIT_STRING_get_length");
}
ret = ossl_str_new((const char *)ASN1_STRING_get0_data(bstr), len, &state);
ASN1_BIT_STRING_free(bstr);
if (state)
rb_jump_tag(state);

return ret;
}
Expand Down Expand Up @@ -746,7 +751,7 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
{
VALUE value, asn1data;
unsigned char *p;
long flag = 0;
int flag = 0;

p = *pp;

Expand Down Expand Up @@ -793,18 +798,18 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
*num_read = hlen + length;

if (tc == sym_UNIVERSAL &&
tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
VALUE klass = *ossl_asn1_info[tag].klass;
VALUE args[4];
args[0] = value;
args[1] = INT2NUM(tag);
args[2] = Qnil;
args[3] = tc;
asn1data = rb_obj_alloc(klass);
ossl_asn1_initialize(4, args, asn1data);
if(tag == V_ASN1_BIT_STRING){
rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag));
}
tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) {
VALUE klass = *ossl_asn1_info[tag].klass;
VALUE args[4];
args[0] = value;
args[1] = INT2NUM(tag);
args[2] = Qnil;
args[3] = tc;
asn1data = rb_obj_alloc(klass);
ossl_asn1_initialize(4, args, asn1data);
if(tag == V_ASN1_BIT_STRING){
rb_ivar_set(asn1data, sivUNUSED_BITS, INT2NUM(flag));
}
}
else {
asn1data = rb_obj_alloc(cASN1Data);
Expand Down
9 changes: 4 additions & 5 deletions ext/openssl/ossl_ns_spki.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,12 @@ ossl_spki_get_challenge(VALUE self)
NETSCAPE_SPKI *spki;

GetSPKI(self, spki);
if (spki->spkac->challenge->length <= 0) {
OSSL_Debug("Challenge.length <= 0?");
return rb_str_new(0, 0);
if (ASN1_STRING_length(spki->spkac->challenge) <= 0) {
OSSL_Debug("Challenge.length <= 0?");
return rb_str_new(0, 0);
}

return rb_str_new((const char *)spki->spkac->challenge->data,
spki->spkac->challenge->length);
return asn1str_to_str(spki->spkac->challenge);
}

/*
Expand Down
16 changes: 8 additions & 8 deletions ext/openssl/ossl_ocsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,6 @@ ossl_ocspbres_get_status(VALUE self)
OCSP_CERTID *cid;
ASN1_TIME *revtime, *thisupd, *nextupd;
int status, reason;
X509_EXTENSION *x509ext;
VALUE ret, ary, ext;
int count, ext_count, i, j;

Expand All @@ -927,7 +926,7 @@ ossl_ocspbres_get_status(VALUE self)
ext = rb_ary_new();
ext_count = OCSP_SINGLERESP_get_ext_count(single);
for(j = 0; j < ext_count; j++){
x509ext = OCSP_SINGLERESP_get_ext(single, j);
const X509_EXTENSION *x509ext = OCSP_SINGLERESP_get_ext(single, j);
rb_ary_push(ext, ossl_x509ext_new(x509ext));
}
rb_ary_push(ary, ext);
Expand Down Expand Up @@ -1358,7 +1357,6 @@ static VALUE
ossl_ocspsres_get_extensions(VALUE self)
{
OCSP_SINGLERESP *sres;
X509_EXTENSION *ext;
int count, i;
VALUE ary;

Expand All @@ -1367,7 +1365,7 @@ ossl_ocspsres_get_extensions(VALUE self)
count = OCSP_SINGLERESP_get_ext_count(sres);
ary = rb_ary_new2(count);
for (i = 0; i < count; i++) {
ext = OCSP_SINGLERESP_get_ext(sres, i);
const X509_EXTENSION *ext = OCSP_SINGLERESP_get_ext(sres, i);
rb_ary_push(ary, ossl_x509ext_new(ext)); /* will dup */
}

Expand Down Expand Up @@ -1565,8 +1563,9 @@ ossl_ocspcid_get_issuer_name_hash(VALUE self)
GetOCSPCertId(self, id);
OCSP_id_get0_info(&name_hash, NULL, NULL, NULL, id);

ret = rb_str_new(NULL, name_hash->length * 2);
ossl_bin2hex(name_hash->data, RSTRING_PTR(ret), name_hash->length);
ret = rb_str_new(NULL, ASN1_STRING_length(name_hash) * 2);
ossl_bin2hex(ASN1_STRING_get0_data(name_hash), RSTRING_PTR(ret),
ASN1_STRING_length(name_hash));

return ret;
}
Expand All @@ -1588,8 +1587,9 @@ ossl_ocspcid_get_issuer_key_hash(VALUE self)
GetOCSPCertId(self, id);
OCSP_id_get0_info(NULL, NULL, &key_hash, NULL, id);

ret = rb_str_new(NULL, key_hash->length * 2);
ossl_bin2hex(key_hash->data, RSTRING_PTR(ret), key_hash->length);
ret = rb_str_new(NULL, ASN1_STRING_length(key_hash) * 2);
ossl_bin2hex(ASN1_STRING_get0_data(key_hash), RSTRING_PTR(ret),
ASN1_STRING_length(key_hash));

return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/openssl/ossl_pkcs7.c
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ static VALUE
ossl_pkcs7si_get_signed_time(VALUE self)
{
PKCS7_SIGNER_INFO *p7si;
ASN1_TYPE *asn1obj;
const ASN1_TYPE *asn1obj;

GetPKCS7si(self, p7si);

Expand Down
Loading
Loading