diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index fb9ccbe46..0de00b62a 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -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) @@ -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. diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c index 4415703db..59dbec6fc 100644 --- a/ext/openssl/openssl_missing.c +++ b/ext/openssl/openssl_missing.c @@ -8,6 +8,7 @@ * (See the file 'LICENCE'.) */ #include RUBY_EXTCONF_H +#include #include /* memcpy() */ #include diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 8629bfe50..9ddb5c8f0 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -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) @@ -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_ */ diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 00eded55c..ce74c0e0a 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -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; diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index 68d42b71e..4d364c1f3 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -64,6 +64,7 @@ #if OSSL_OPENSSL_PREREQ(3, 0, 0) # define OSSL_USE_PROVIDER +# include #endif /* @@ -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 diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index f26a4759c..357932138 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -17,17 +17,18 @@ 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); @@ -35,7 +36,7 @@ asn1time_to_time(const ASN1_TIME *time) 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; @@ -44,7 +45,7 @@ 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) { @@ -52,7 +53,7 @@ asn1time_to_time(const ASN1_TIME *time) } else if (count != 6) { ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format: \"%s\"", - time->data); + ASN1_STRING_get0_data(time)); } break; default: @@ -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)); } /* @@ -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); @@ -210,7 +212,7 @@ 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; @@ -218,11 +220,11 @@ obj_to_asn1bstr(VALUE obj, long unused_bits) 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; } @@ -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; } @@ -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; @@ -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); diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c index 9bed1f330..ac9937eaa 100644 --- a/ext/openssl/ossl_ns_spki.c +++ b/ext/openssl/ossl_ns_spki.c @@ -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); } /* diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c index df986bb3e..b4b326fbd 100644 --- a/ext/openssl/ossl_ocsp.c +++ b/ext/openssl/ossl_ocsp.c @@ -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; @@ -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); @@ -1358,7 +1357,6 @@ static VALUE ossl_ocspsres_get_extensions(VALUE self) { OCSP_SINGLERESP *sres; - X509_EXTENSION *ext; int count, i; VALUE ary; @@ -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 */ } @@ -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; } @@ -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; } diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c index 7e5fb9c1b..41ace21d2 100644 --- a/ext/openssl/ossl_pkcs7.c +++ b/ext/openssl/ossl_pkcs7.c @@ -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); diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 9e0835d38..c579135bd 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -636,6 +636,30 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) #endif #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY + +#ifndef OSSL_USE_PROVIDER +static int +lookup_pkey_type(VALUE type) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id; + + StringValue(type); + /* + * XXX: EVP_PKEY_asn1_find_str() looks up a PEM type string. Should we use + * OBJ_txt2nid() instead (and then somehow check if the NID is an acceptable + * EVP_PKEY type)? + * It is probably fine, though, since it can handle all algorithms that + * support raw keys in 1.1.1: { X25519, X448, ED25519, ED448, HMAC }. + */ + ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); + if (!ameth) + ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); + return pkey_id; +} +#endif + /* * call-seq: * OpenSSL::PKey.new_raw_private_key(algo, string) -> PKey @@ -647,22 +671,23 @@ static VALUE ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key) { EVP_PKEY *pkey; - const EVP_PKEY_ASN1_METHOD *ameth; - int pkey_id; size_t keylen; - StringValue(type); StringValue(key); - ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); - if (!ameth) - ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); - EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); - keylen = RSTRING_LEN(key); +#ifdef OSSL_USE_PROVIDER + pkey = EVP_PKEY_new_raw_private_key_ex(NULL, StringValueCStr(type), NULL, + (unsigned char *)RSTRING_PTR(key), + keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key_ex"); +#else + int pkey_id = lookup_pkey_type(type); pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key"); +#endif return ossl_pkey_new(pkey); } @@ -680,22 +705,23 @@ static VALUE ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key) { EVP_PKEY *pkey; - const EVP_PKEY_ASN1_METHOD *ameth; - int pkey_id; size_t keylen; - StringValue(type); StringValue(key); - ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); - if (!ameth) - ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); - EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); - keylen = RSTRING_LEN(key); +#ifdef OSSL_USE_PROVIDER + pkey = EVP_PKEY_new_raw_public_key_ex(NULL, StringValueCStr(type), NULL, + (unsigned char *)RSTRING_PTR(key), + keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key_ex"); +#else + int pkey_id = lookup_pkey_type(type); pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key"); +#endif return ossl_pkey_new(pkey); } @@ -715,6 +741,10 @@ ossl_pkey_oid(VALUE self) GetPKey(self, pkey); nid = EVP_PKEY_id(pkey); +#ifdef OSSL_USE_PROVIDER + if (nid == EVP_PKEY_KEYMGMT) + ossl_raise(ePKeyError, "EVP_PKEY_id"); +#endif return rb_str_new_cstr(OBJ_nid2sn(nid)); } @@ -728,13 +758,23 @@ static VALUE ossl_pkey_inspect(VALUE self) { EVP_PKEY *pkey; - int nid; GetPKey(self, pkey); - nid = EVP_PKEY_id(pkey); - return rb_sprintf("#<%"PRIsVALUE":%p oid=%s>", - rb_class_name(CLASS_OF(self)), (void *)self, - OBJ_nid2sn(nid)); + VALUE str = rb_sprintf("#<%"PRIsVALUE":%p", + rb_obj_class(self), (void *)self); + int nid = EVP_PKEY_id(pkey); +#ifdef OSSL_USE_PROVIDER + if (nid != EVP_PKEY_KEYMGMT) +#endif + rb_str_catf(str, " oid=%s", OBJ_nid2sn(nid)); +#ifdef OSSL_USE_PROVIDER + rb_str_catf(str, " type_name=%s", EVP_PKEY_get0_type_name(pkey)); + const OSSL_PROVIDER *prov = EVP_PKEY_get0_provider(pkey); + if (prov) + rb_str_catf(str, " provider=%s", OSSL_PROVIDER_get0_name(prov)); +#endif + rb_str_catf(str, ">"); + return str; } /* diff --git a/ext/openssl/ossl_provider.c b/ext/openssl/ossl_provider.c index 981c6ccdc..6ec818799 100644 --- a/ext/openssl/ossl_provider.c +++ b/ext/openssl/ossl_provider.c @@ -5,8 +5,6 @@ #include "ossl.h" #ifdef OSSL_USE_PROVIDER -# include - #define NewProvider(klass) \ TypedData_Wrap_Struct((klass), &ossl_provider_type, 0) #define SetProvider(obj, provider) do { \ diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c index f698bdc7f..7d01b0b8b 100644 --- a/ext/openssl/ossl_ts.c +++ b/ext/openssl/ossl_ts.c @@ -288,7 +288,7 @@ ossl_ts_req_get_msg_imprint(VALUE self) mi = TS_REQ_get_msg_imprint(req); hashed_msg = TS_MSG_IMPRINT_get_msg(mi); - ret = rb_str_new((const char *)hashed_msg->data, hashed_msg->length); + ret = asn1str_to_str(hashed_msg); return ret; } @@ -497,7 +497,7 @@ ossl_ts_req_to_der(VALUE self) ossl_raise(eTimestampError, "Message imprint missing algorithm"); hashed_msg = TS_MSG_IMPRINT_get_msg(mi); - if (!hashed_msg->length) + if (!ASN1_STRING_length(hashed_msg)) ossl_raise(eTimestampError, "Message imprint missing hashed message"); return asn1_to_der((void *)req, (int (*)(void *, unsigned char **))i2d_TS_REQ); @@ -730,7 +730,7 @@ ossl_ts_resp_get_tsa_certificate(VALUE self) TS_RESP *resp; PKCS7 *p7; PKCS7_SIGNER_INFO *ts_info; - X509 *cert; + const X509 *cert; GetTSResponse(self, resp); if (!(p7 = TS_RESP_get_token(resp))) @@ -974,7 +974,7 @@ ossl_ts_token_info_get_msg_imprint(VALUE self) GetTSTokenInfo(self, info); mi = TS_TST_INFO_get_msg_imprint(info); hashed_msg = TS_MSG_IMPRINT_get_msg(mi); - ret = rb_str_new((const char *)hashed_msg->data, hashed_msg->length); + ret = asn1str_to_str(hashed_msg); return ret; } diff --git a/ext/openssl/ossl_x509.h b/ext/openssl/ossl_x509.h index 4fadfa6b8..7448ca2e7 100644 --- a/ext/openssl/ossl_x509.h +++ b/ext/openssl/ossl_x509.h @@ -30,7 +30,7 @@ void Init_ossl_x509(void); extern VALUE cX509Attr; extern VALUE eX509AttrError; -VALUE ossl_x509attr_new(X509_ATTRIBUTE *); +VALUE ossl_x509attr_new(const X509_ATTRIBUTE *); X509_ATTRIBUTE *GetX509AttrPtr(VALUE); void Init_ossl_x509attr(void); @@ -40,7 +40,7 @@ void Init_ossl_x509attr(void); extern VALUE cX509Cert; extern VALUE eX509CertError; -VALUE ossl_x509_new(X509 *); +VALUE ossl_x509_new(const X509 *); X509 *GetX509CertPtr(VALUE); X509 *DupX509CertPtr(VALUE); void Init_ossl_x509cert(void); @@ -51,7 +51,7 @@ void Init_ossl_x509cert(void); extern VALUE cX509CRL; extern VALUE eX509CRLError; -VALUE ossl_x509crl_new(X509_CRL *); +VALUE ossl_x509crl_new(const X509_CRL *); X509_CRL *GetX509CRLPtr(VALUE); void Init_ossl_x509crl(void); @@ -62,7 +62,7 @@ extern VALUE cX509Ext; extern VALUE cX509ExtFactory; extern VALUE eX509ExtError; -VALUE ossl_x509ext_new(X509_EXTENSION *); +VALUE ossl_x509ext_new(const X509_EXTENSION *); X509_EXTENSION *GetX509ExtPtr(VALUE); void Init_ossl_x509ext(void); @@ -72,7 +72,7 @@ void Init_ossl_x509ext(void); extern VALUE cX509Name; extern VALUE eX509NameError; -VALUE ossl_x509name_new(X509_NAME *); +VALUE ossl_x509name_new(const X509_NAME *); X509_NAME *GetX509NamePtr(VALUE); void Init_ossl_x509name(void); @@ -91,7 +91,7 @@ void Init_ossl_x509req(void); extern VALUE cX509Rev; extern VALUE eX509RevError; -VALUE ossl_x509revoked_new(X509_REVOKED *); +VALUE ossl_x509revoked_new(const X509_REVOKED *); X509_REVOKED *DupX509RevokedPtr(VALUE); void Init_ossl_x509revoked(void); diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index d1d8bb5e9..005714843 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -48,7 +48,7 @@ static const rb_data_type_t ossl_x509attr_type = { * Public */ VALUE -ossl_x509attr_new(X509_ATTRIBUTE *attr) +ossl_x509attr_new(const X509_ATTRIBUTE *attr) { X509_ATTRIBUTE *new; VALUE obj; @@ -57,7 +57,8 @@ ossl_x509attr_new(X509_ATTRIBUTE *attr) if (!attr) { new = X509_ATTRIBUTE_new(); } else { - new = X509_ATTRIBUTE_dup(attr); + /* OpenSSL 1.1.1 takes a non-const pointer */ + new = X509_ATTRIBUTE_dup((X509_ATTRIBUTE *)attr); } if (!new) { ossl_raise(eX509AttrError, NULL); @@ -174,7 +175,7 @@ static VALUE ossl_x509attr_get_oid(VALUE self) { X509_ATTRIBUTE *attr; - ASN1_OBJECT *oid; + const ASN1_OBJECT *oid; BIO *out; VALUE ret; int nid; @@ -186,7 +187,7 @@ ossl_x509attr_get_oid(VALUE self) else{ if (!(out = BIO_new(BIO_s_mem()))) ossl_raise(eX509AttrError, NULL); - i2a_ASN1_OBJECT(out, oid); + i2a_ASN1_OBJECT(out, (ASN1_OBJECT *)oid); ret = ossl_membio2str(out); } @@ -214,7 +215,7 @@ ossl_x509attr_set_value(VALUE self, VALUE value) GetX509Attr(self, attr); if (X509_ATTRIBUTE_count(attr)) { /* populated, reset first */ - ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); + const ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1); if (!new_attr) ossl_raise(eX509AttrError, NULL); @@ -256,7 +257,7 @@ ossl_x509attr_get_value(VALUE self) count = X509_ATTRIBUTE_count(attr); for (i = 0; i < count; i++) - sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i)); + sk_ASN1_TYPE_push(sk, (ASN1_TYPE *)X509_ATTRIBUTE_get0_type(attr, i)); if ((len = i2d_ASN1_SET_ANY(sk, NULL)) <= 0) { sk_ASN1_TYPE_free(sk); diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index aa6b9bb7c..2727278ed 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -48,7 +48,7 @@ static const rb_data_type_t ossl_x509_type = { * Public */ VALUE -ossl_x509_new(X509 *x509) +ossl_x509_new(const X509 *x509) { X509 *new; VALUE obj; @@ -57,7 +57,8 @@ ossl_x509_new(X509 *x509) if (!x509) { new = X509_new(); } else { - new = X509_dup(x509); + /* OpenSSL 1.1.1 takes a non-const pointer */ + new = X509_dup((X509 *)x509); } if (!new) { ossl_raise(eX509CertError, NULL); @@ -351,7 +352,7 @@ static VALUE ossl_x509_get_subject(VALUE self) { X509 *x509; - X509_NAME *name; + const X509_NAME *name; GetX509(self, x509); if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */ @@ -386,7 +387,7 @@ static VALUE ossl_x509_get_issuer(VALUE self) { X509 *x509; - X509_NAME *name; + const X509_NAME *name; GetX509(self, x509); if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */ @@ -608,7 +609,6 @@ ossl_x509_get_extensions(VALUE self) { X509 *x509; int count, i; - X509_EXTENSION *ext; VALUE ary; GetX509(self, x509); @@ -618,7 +618,7 @@ ossl_x509_get_extensions(VALUE self) } ary = rb_ary_new2(count); for (i=0; idata, value->length); + return asn1str_to_str(value); } static VALUE diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index 9591912f7..90ec2d96a 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -53,7 +53,7 @@ static const rb_data_type_t ossl_x509name_type = { * Public */ VALUE -ossl_x509name_new(X509_NAME *name) +ossl_x509name_new(const X509_NAME *name) { X509_NAME *new; VALUE obj; @@ -62,7 +62,8 @@ ossl_x509name_new(X509_NAME *name) if (!name) { new = X509_NAME_new(); } else { - new = X509_NAME_dup(name); + /* OpenSSL 1.1.1 takes a non-const pointer */ + new = X509_NAME_dup((X509_NAME *)name); } if (!new) { ossl_raise(eX509NameError, NULL); @@ -360,7 +361,7 @@ ossl_x509name_to_a(VALUE self) } ret = rb_ary_new2(entries); for (i=0; itype)); + value = (ASN1_STRING *)X509_NAME_ENTRY_get_data(entry); + ary = rb_ary_new3(3, vname, asn1str_to_str(value), + INT2NUM(ASN1_STRING_type(value))); rb_ary_push(ret, ary); } return ret; diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c index f05818515..ef8e0bccf 100644 --- a/ext/openssl/ossl_x509req.c +++ b/ext/openssl/ossl_x509req.c @@ -230,7 +230,7 @@ static VALUE ossl_x509req_get_subject(VALUE self) { X509_REQ *req; - X509_NAME *name; + const X509_NAME *name; GetX509Req(self, req); if (!(name = X509_REQ_get_subject_name(req))) { /* NO DUP - don't free */ @@ -348,7 +348,7 @@ ossl_x509req_get_attributes(VALUE self) { X509_REQ *req; int count, i; - X509_ATTRIBUTE *attr; + const X509_ATTRIBUTE *attr; VALUE ary; GetX509Req(self, req); diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c index 108447c86..b4916d34b 100644 --- a/ext/openssl/ossl_x509revoked.c +++ b/ext/openssl/ossl_x509revoked.c @@ -48,7 +48,7 @@ static const rb_data_type_t ossl_x509rev_type = { * PUBLIC */ VALUE -ossl_x509revoked_new(X509_REVOKED *rev) +ossl_x509revoked_new(const X509_REVOKED *rev) { X509_REVOKED *new; VALUE obj; @@ -57,7 +57,8 @@ ossl_x509revoked_new(X509_REVOKED *rev) if (!rev) { new = X509_REVOKED_new(); } else { - new = X509_REVOKED_dup(rev); + /* OpenSSL 1.1.1 takes a non-const pointer */ + new = X509_REVOKED_dup((X509_REVOKED *)rev); } if (!new) { ossl_raise(eX509RevError, NULL); @@ -189,7 +190,7 @@ ossl_x509revoked_get_extensions(VALUE self) { X509_REVOKED *rev; int count, i; - X509_EXTENSION *ext; + const X509_EXTENSION *ext; VALUE ary; GetX509Rev(self, rev); diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index f27381ca9..110b5934d 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -521,10 +521,8 @@ static void ossl_x509stctx_free(void *ptr) { X509_STORE_CTX *ctx = ptr; - if (X509_STORE_CTX_get0_untrusted(ctx)) - sk_X509_pop_free(X509_STORE_CTX_get0_untrusted(ctx), X509_free); - if (X509_STORE_CTX_get0_cert(ctx)) - X509_free(X509_STORE_CTX_get0_cert(ctx)); + sk_X509_pop_free(X509_STORE_CTX_get0_untrusted(ctx), X509_free); + X509_free((X509 *)X509_STORE_CTX_get0_cert(ctx)); X509_STORE_CTX_free(ctx); } @@ -765,7 +763,7 @@ static VALUE ossl_x509stctx_get_curr_crl(VALUE self) { X509_STORE_CTX *ctx; - X509_CRL *crl; + const X509_CRL *crl; GetX509StCtx(self, ctx); crl = X509_STORE_CTX_get0_current_crl(ctx); diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index 811d5103d..141575267 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -8,6 +8,7 @@ def test_generic_oid_inspect assert_instance_of OpenSSL::PKey::RSA, rsa assert_equal "rsaEncryption", rsa.oid assert_match %r{oid=rsaEncryption}, rsa.inspect + assert_match %r{type_name=RSA}, rsa.inspect if openssl?(3, 0, 0) # X25519 private key x25519_pem = <<~EOF @@ -171,6 +172,8 @@ def test_x25519 pend "X25519 is not implemented" end assert_instance_of OpenSSL::PKey::PKey, alice + assert_equal "X25519", alice.oid + assert_match %r{oid=X25519}, alice.inspect assert_equal alice_pem, alice.private_to_pem assert_equal bob_pem, bob.public_to_pem assert_equal [shared_secret].pack("H*"), alice.derive(bob) @@ -193,6 +196,25 @@ def test_x25519 bob_public_raw end + def test_ml_dsa + # AWS-LC also supports ML-DSA, but it's implemented in a different way + return unless openssl?(3, 5, 0) + + pkey = OpenSSL::PKey.generate_key("ML-DSA-44") + assert_match(/type_name=ML-DSA-44/, pkey.inspect) + sig = pkey.sign(nil, "data") + assert_equal(2420, sig.bytesize) + assert_equal(true, pkey.verify(nil, sig, "data")) + + pub2 = OpenSSL::PKey.read(pkey.public_to_der) + assert_equal(true, pub2.verify(nil, sig, "data")) + + raw_public_key = pkey.raw_public_key + assert_equal(1312, raw_public_key.bytesize) + pub3 = OpenSSL::PKey.new_raw_public_key("ML-DSA-44", raw_public_key) + assert_equal(true, pub3.verify(nil, sig, "data")) + end + def raw_initialize pend "Ed25519 is not implemented" unless openssl?(1, 1, 1) # >= v1.1.1 diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb index 61c55c60b..d340c4cb7 100644 --- a/test/openssl/test_pkey_rsa.rb +++ b/test/openssl/test_pkey_rsa.rb @@ -172,7 +172,7 @@ def test_verify_empty_rsa assert_raise(OpenSSL::PKey::PKeyError, "[Bug #12783]") { rsa.verify("SHA1", "a", "b") } - end + end unless openssl?(3, 0, 0) def test_sign_verify_pss key = Fixtures.pkey("rsa1024") diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb index 07dc9a343..240bb199c 100644 --- a/test/openssl/test_ssl.rb +++ b/test/openssl/test_ssl.rb @@ -1634,7 +1634,9 @@ def test_tmp_dh_callback } } start_server(ctx_proc: ctx_proc) do |port| - server_connect(port) { |ssl| + ctx = OpenSSL::SSL::SSLContext.new + ctx.ecdh_curves = "P-256" # Exclude RFC 7919 groups + server_connect(port, ctx) { |ssl| assert called, "dh callback should be called" assert_equal dh.to_der, ssl.tmp_key.to_der } @@ -1761,7 +1763,9 @@ def test_tmp_dh ctx.tmp_dh = dh } start_server(ctx_proc: ctx_proc) do |port| - server_connect(port) { |ssl| + ctx = OpenSSL::SSL::SSLContext.new + ctx.ecdh_curves = "P-256" # Exclude RFC 7919 groups + server_connect(port, ctx) { |ssl| assert_equal dh.to_der, ssl.tmp_key.to_der } end