From cd45a57aafddb908eb3a56e118b4c01899765d18 Mon Sep 17 00:00:00 2001
From: Nicola Tuveri <nic.tuv@gmail.com>
Date: Tue, 7 Jan 2020 01:19:13 +0200
Subject: [PATCH 031/217] [EC] Constify internal EC_KEY pointer usage

A pair of internal functions related to EC_KEY handling could benefit
from declaring `EC_KEY *` variables as `const`, providing clarity for
callers and readers of the code, in addition to enlisting the compiler
in preventing some mistakes.

(cherry picked from commit cd701de96a147260c2290d85af8a0656120a8ff8)

In master `id2_ECParameters` and most of the ASN1 public functions have
been properly constified in their signature.

Unfortunately this has been deemed not doable in a patch release for
1.1.1 as, in subtle ways, this would break API compatibility.
See the discussion at https://github.com/openssl/openssl/pull/9347 for
more details about this.

This constification commit should still be portable w.r.t. our criteria,
as the constification happens only on internal functions.

The fix here is to explicitly discard the const qualifier before the
call to `i2d_ECParameters`, which should be safe anyway because we can
expect `i2d_ECParameters()` to treat the first argument as if it was
const.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11127)
---
 crypto/ec/ec_ameth.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 2210383..b7b82e5 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -23,7 +23,7 @@ static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
 static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
 #endif
 
-static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
+static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key)
 {
     const EC_GROUP *group;
     int nid;
@@ -43,7 +43,17 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
         pstr = ASN1_STRING_new();
         if (pstr == NULL)
             return 0;
-        pstr->length = i2d_ECParameters(ec_key, &pstr->data);
+
+        /*
+         * The cast in the following line is intentional as the
+         * `i2d_ECParameters` signature can't be constified (see discussion at
+         * https://github.com/openssl/openssl/pull/9347 where related and
+         * required constification backports were rejected).
+         *
+         * This cast should be safe anyway, because we can expect
+         * `i2d_ECParameters()` to treat the first argument as if it was const.
+         */
+        pstr->length = i2d_ECParameters((EC_KEY *)ec_key, &pstr->data);
         if (pstr->length <= 0) {
             ASN1_STRING_free(pstr);
             ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
@@ -57,7 +67,7 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
 
 static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
 {
-    EC_KEY *ec_key = pkey->pkey.ec;
+    const EC_KEY *ec_key = pkey->pkey.ec;
     void *pval = NULL;
     int ptype;
     unsigned char *penc = NULL, *p;
-- 
1.8.3.1

