• Bug#1033573: marked as done (unblock: ruby3.1/3.1.2-7) (2/2)

    From Debian Bug Tracking System@21:1/5 to All on Wed Mar 29 22:30:01 2023
    [continued from previous message]

    /* Then check PEM; multiple OSSL_DECODER_from_bio() calls may be needed */ - OSSL_BIO_reset(bio);
    if (OSSL_DECODER_CTX_set_input_type(dctx, "PEM") != 1)
    goto out;
    - while (OSSL_DECODER_from_bio(dctx, bio) != 1) {
    - if (BIO_eof(bio))
    + /*
    + * First check for private key formats. This is to keep compatibility with + * ruby/openssl < 3.0 which decoded the following as a private key.
    + *
    + * $ openssl ecparam -name prime256v1 -genkey -outform PEM
    + * -----BEGIN EC PARAMETERS-----
    + * BggqhkjOPQMBBw==
    + * -----END EC PARAMETERS-----
    + * -----BEGIN EC PRIVATE KEY-----
    + * MHcCAQEEIAG8ugBbA5MHkqnZ9ujQF93OyUfL9tk8sxqM5Wv5tKg5oAoGCCqGSM49
    + * AwEHoUQDQgAEVcjhJfkwqh5C7kGuhAf8XaAjVuG5ADwb5ayg/cJijCgs+GcXeedj
    + * 86avKpGH84DXUlB23C/kPt+6fXYlitUmXQ==
    + * -----END EC PRIVATE KEY-----
    + *
    + * While the first PEM block is a proper encoding of ECParameters, thus
    + * OSSL_DECODER_from_bio() would pick it up, ruby/openssl used to return
    + * the latter instead. Existing applications expect this behavior.
    + *
    + * Note that normally, the input is supposed to contain a single decodable + * PEM block only, so this special handling should not create a new problem.
    + */
    + OSSL_DECODER_CTX_set_selection(dctx, EVP_PKEY_KEYPAIR);
    + while (1) {
    + if (OSSL_DECODER_from_bio(dctx, bio) == 1)
    goto out;
    + if (BIO_eof(bio))
    + break;
    pos2 = BIO_tell(bio);
    if (pos2 < 0 || pos2 <= pos)
    + break;
    + ossl_clear_error();
    + pos = pos2;
    + }
    +
    + OSSL_BIO_reset(bio);
    + OSSL_DECODER_CTX_set_selection(dctx, 0);
    + while (1) {
    + if (OSSL_DECODER_from_bio(dctx, bio) == 1)
    goto out;
    + if (BIO_eof(bio))
    + break;
    + pos2 = BIO_tell(bio);
    + if (pos2 < 0 || pos2 <= pos)
    + break;
    + ossl_clear_error();
    pos = pos2;
    }

    @@ -200,6 +239,7 @@ static VALUE
    pkey_ctx_apply_options0(VALUE args_v)
    {
    VALUE *args = (VALUE *)args_v;
    + Check_Type(args[1], T_HASH);

    rb_block_call(args[1], rb_intern("each"), 0, NULL,
    pkey_ctx_apply_options_i, args[0]);
    diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
    index dee2154..06d59c2 100644
    --- a/ext/openssl/ossl_pkey_ec.c
    +++ b/ext/openssl/ossl_pkey_ec.c
    @@ -414,6 +414,8 @@ ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
    EC_KEY *ec;

    GetEC(self, ec);
    + if (EC_KEY_get0_public_key(ec) == NULL)
    + ossl_raise(eECError, "can't export - no public key set");
    if (EC_KEY_get0_private_key(ec))
    return ossl_pkey_export_traditional(argc, argv, self, 0);
    else
    @@ -432,6 +434,8 @@ ossl_ec_key_to_der(VALUE self)
    EC_KEY *ec;

    GetEC(self, ec);
    + if (EC_KEY_get0_public_key(ec) == NULL)
    + ossl_raise(eECError, "can't export - no public key set");
    if (EC_KEY_get0_private_key(ec))
    return ossl_pkey_export_traditional(0, NULL, self, 1);
    else
    diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c
    index 996f184..9443541 100644
    --- a/ext/openssl/ossl_x509cert.c
    +++ b/ext/openssl/ossl_x509cert.c
    @@ -642,12 +642,12 @@ ossl_x509_set_extensions(VALUE self, VALUE ary)
    OSSL_Check_Kind(RARRAY_AREF(ary, i