[openssl] master update

nic.tuv at gmail.com nic.tuv at gmail.com
Tue Jul 7 08:57:37 UTC 2020


The branch master has been updated
       via  1c9761d0b547d2d135037d215cd16feb4d0b698c (commit)
       via  466d30c0d7fa861a5fcbaebd2e2010a8c2aea322 (commit)
       via  e0137ca92b4abf65acde15b255ae58d7e76af22f (commit)
      from  8c330e1939d6b7db93a963116354ef80ca0babb3 (commit)


- Log -----------------------------------------------------------------
commit 1c9761d0b547d2d135037d215cd16feb4d0b698c
Author: Nicola Tuveri <nic.tuv at gmail.com>
Date:   Sun Jun 28 20:03:53 2020 +0300

    [test][15-test_genec] Improve EC tests with genpkey
    
    Test separately EC parameters and EC key generation.
    
    Some curves only support explicit params encoding.
    
    For some curves we have had cases in which generating the parameters
    under certain conditions failed, while generating and serializing a key
    under the same conditions did not.
    See <https://github.com/openssl/openssl/issues/12306> for more details.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12307)

commit 466d30c0d7fa861a5fcbaebd2e2010a8c2aea322
Author: Nicola Tuveri <nic.tuv at gmail.com>
Date:   Sat Jun 27 01:42:49 2020 +0300

    [apps/genpkey] exit status should not be 0 on output errors
    
    If the key is to be serialized or printed as text and the framework
    returns an error, the app should signal the failure to the user using
    a non-zero exit status.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/12305)

commit e0137ca92b4abf65acde15b255ae58d7e76af22f
Author: Nicola Tuveri <nic.tuv at gmail.com>
Date:   Mon Jun 29 00:53:46 2020 +0300

    [EC][ASN1] Detect missing OID when serializing EC parameters and keys
    
    The following built-in curves do not have an assigned OID:
    
    - Oakley-EC2N-3
    - Oakley-EC2N-4
    
    In general we shouldn't assume that an OID is always available.
    
    This commit detects such cases, raises an error and returns appropriate
    return values so that the condition can be detected and correctly
    handled by the callers, when serializing EC parameters or EC keys with
    the default `ec_param_enc:named_curve`.
    
    Fixes #12306
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/12313)

-----------------------------------------------------------------------

Summary of changes:
 apps/genpkey.c                                     |   6 +-
 crypto/ec/ec_ameth.c                               |   9 +-
 crypto/ec/ec_asn1.c                                |  11 +-
 crypto/ec/ec_err.c                                 |   1 +
 crypto/err/openssl.txt                             |   2 +
 crypto/pem/pem_lib.c                               |   2 +-
 include/openssl/ecerr.h                            |   1 +
 providers/common/include/prov/providercommonerr.h  |   1 +
 providers/common/provider_err.c                    |   1 +
 .../implementations/serializers/serializer_ec.c    |   8 ++
 test/recipes/15-test_genec.t                       | 133 ++++++++++++++++++---
 11 files changed, 155 insertions(+), 20 deletions(-)

diff --git a/apps/genpkey.c b/apps/genpkey.c
index 8954ef19c7..4a4a83fd40 100644
--- a/apps/genpkey.c
+++ b/apps/genpkey.c
@@ -189,9 +189,12 @@ int genpkey_main(int argc, char **argv)
         goto end;
     }
 
+    ret = 0;
+
     if (rv <= 0) {
         BIO_puts(bio_err, "Error writing key\n");
         ERR_print_errors(bio_err);
+        ret = 1;
     }
 
     if (text) {
@@ -203,11 +206,10 @@ int genpkey_main(int argc, char **argv)
         if (rv <= 0) {
             BIO_puts(bio_err, "Error printing key\n");
             ERR_print_errors(bio_err);
+            ret = 1;
         }
     }
 
-    ret = 0;
-
  end:
     EVP_PKEY_free(pkey);
     EVP_PKEY_CTX_free(ctx);
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 761f697850..8a33b3232c 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -43,7 +43,14 @@ static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key)
         && (nid = EC_GROUP_get_curve_name(group)))
         /* we have a 'named curve' => just set the OID */
     {
-        *ppval = OBJ_nid2obj(nid);
+        ASN1_OBJECT *asn1obj = OBJ_nid2obj(nid);
+
+        if (asn1obj == NULL || OBJ_length(asn1obj) == 0) {
+            ASN1_OBJECT_free(asn1obj);
+            ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_OID);
+            return 0;
+        }
+        *ppval = asn1obj;
         *pptype = V_ASN1_OBJECT;
     } else {                    /* explicit parameters */
 
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index a53573cc92..654a12ad60 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -553,9 +553,16 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
          */
         tmp = EC_GROUP_get_curve_name(group);
         if (tmp) {
-            ret->type = 0;
-            if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
+            ASN1_OBJECT *asn1obj = OBJ_nid2obj(tmp);
+
+            if (asn1obj == NULL || OBJ_length(asn1obj) == 0) {
+                ASN1_OBJECT_free(asn1obj);
+                ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, EC_R_MISSING_OID);
                 ok = 0;
+            } else {
+                ret->type = 0;
+                ret->value.named_curve = asn1obj;
+            }
         } else
             /* we don't know the nid => ERROR */
             ok = 0;
diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c
index d775ced93a..afb2696285 100644
--- a/crypto/ec/ec_err.c
+++ b/crypto/ec/ec_err.c
@@ -70,6 +70,7 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
     {ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_POST_FAILURE), "ladder post failure"},
     {ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_PRE_FAILURE), "ladder pre failure"},
     {ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_STEP_FAILURE), "ladder step failure"},
+    {ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_OID), "missing OID"},
     {ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PARAMETERS), "missing parameters"},
     {ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PRIVATE_KEY), "missing private key"},
     {ERR_PACK(ERR_LIB_EC, 0, EC_R_NEED_NEW_SETUP_VALUES),
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index bc39b37cd0..579c2dce9a 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2439,6 +2439,7 @@ EC_R_KEYS_NOT_SET:140:keys not set
 EC_R_LADDER_POST_FAILURE:136:ladder post failure
 EC_R_LADDER_PRE_FAILURE:153:ladder pre failure
 EC_R_LADDER_STEP_FAILURE:162:ladder step failure
+EC_R_MISSING_OID:167:missing OID
 EC_R_MISSING_PARAMETERS:124:missing parameters
 EC_R_MISSING_PRIVATE_KEY:125:missing private key
 EC_R_NEED_NEW_SETUP_VALUES:157:need new setup values
@@ -2886,6 +2887,7 @@ PROV_R_MISSING_CONSTANT:156:missing constant
 PROV_R_MISSING_KEY:128:missing key
 PROV_R_MISSING_MAC:150:missing mac
 PROV_R_MISSING_MESSAGE_DIGEST:129:missing message digest
+PROV_R_MISSING_OID:209:missing OID
 PROV_R_MISSING_PASS:130:missing pass
 PROV_R_MISSING_SALT:131:missing salt
 PROV_R_MISSING_SECRET:132:missing secret
diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
index c170f60bcd..bd20bbb783 100644
--- a/crypto/pem/pem_lib.c
+++ b/crypto/pem/pem_lib.c
@@ -334,7 +334,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
         }
     }
 
-    if ((dsize = i2d(x, NULL)) < 0) {
+    if ((dsize = i2d(x, NULL)) <= 0) {
         PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB);
         dsize = 0;
         goto err;
diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h
index 033c94d9a9..b12e222510 100644
--- a/include/openssl/ecerr.h
+++ b/include/openssl/ecerr.h
@@ -264,6 +264,7 @@ int ERR_load_EC_strings(void);
 #  define EC_R_LADDER_POST_FAILURE                         136
 #  define EC_R_LADDER_PRE_FAILURE                          153
 #  define EC_R_LADDER_STEP_FAILURE                         162
+#  define EC_R_MISSING_OID                                 167
 #  define EC_R_MISSING_PARAMETERS                          124
 #  define EC_R_MISSING_PRIVATE_KEY                         125
 #  define EC_R_NEED_NEW_SETUP_VALUES                       157
diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h
index b7fd2c2bf4..c21537fd4f 100644
--- a/providers/common/include/prov/providercommonerr.h
+++ b/providers/common/include/prov/providercommonerr.h
@@ -113,6 +113,7 @@ int ERR_load_PROV_strings(void);
 # define PROV_R_MISSING_KEY                               128
 # define PROV_R_MISSING_MAC                               150
 # define PROV_R_MISSING_MESSAGE_DIGEST                    129
+# define PROV_R_MISSING_OID                               209
 # define PROV_R_MISSING_PASS                              130
 # define PROV_R_MISSING_SALT                              131
 # define PROV_R_MISSING_SECRET                            132
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index 08978189b9..7a0e0c595d 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -112,6 +112,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MAC), "missing mac"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MESSAGE_DIGEST),
     "missing message digest"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_OID), "missing OID"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_PASS), "missing pass"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SALT), "missing salt"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SECRET), "missing secret"},
diff --git a/providers/implementations/serializers/serializer_ec.c b/providers/implementations/serializers/serializer_ec.c
index 4d81651c5a..0dbc889d34 100644
--- a/providers/implementations/serializers/serializer_ec.c
+++ b/providers/implementations/serializers/serializer_ec.c
@@ -11,6 +11,7 @@
 #include "crypto/ec.h"
 #include "prov/bio.h"             /* ossl_prov_bio_printf() */
 #include "prov/implementations.h" /* ec_keymgmt_functions */
+#include "prov/providercommonerr.h" /* PROV_R_MISSING_OID */
 #include "serializer_local.h"
 
 void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new,
@@ -117,6 +118,13 @@ int ossl_prov_prepare_ec_params(const void *eckey, int nid,
         return 0;
     }
 
+    if (OBJ_length(params) == 0) {
+        /* Some curves might not have an associated OID */
+        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID);
+        ASN1_OBJECT_free(params);
+        return 0;
+    }
+
     *pstr = params;
     *pstrtype = V_ASN1_OBJECT;
     return 1;
diff --git a/test/recipes/15-test_genec.t b/test/recipes/15-test_genec.t
index d4547e5849..b46147ca10 100644
--- a/test/recipes/15-test_genec.t
+++ b/test/recipes/15-test_genec.t
@@ -23,13 +23,13 @@ use OpenSSL::Test::Utils;
 # The remaining argument are passed unchecked to 'run'.
 
 # 1:    the result of app() or similar, i.e. something you can pass to
-sub supported {
+sub supported_pass {
     my $str = shift;
 
     ok(run(@_), $str);
 }
 
-sub unsupported {
+sub unsupported_pass {
     my $str = shift;
  TODO: {
         local $TODO = "Currently not supported";
@@ -38,6 +38,20 @@ sub unsupported {
     }
 }
 
+sub supported_fail {
+    my $str = shift;
+
+    ok(!run(@_), $str);
+}
+
+sub unsupported_fail {
+    my $str = shift;
+ TODO: {
+        local $TODO = "Currently not supported";
+
+        ok(!run(@_), $str);
+    }
+}
 
 setup("test_genec");
 
@@ -127,10 +141,14 @@ my @binary_curves = qw(
     wap-wsg-idm-ecid-wtls5
     wap-wsg-idm-ecid-wtls10
     wap-wsg-idm-ecid-wtls11
-    Oakley-EC2N-3
-    Oakley-EC2N-4
 );
 
+my @explicit_only_curves = ();
+push(@explicit_only_curves, qw(
+        Oakley-EC2N-3
+        Oakley-EC2N-4
+    )) if !disabled("ec2m");
+
 my @other_curves = ();
 push(@other_curves, 'SM2')
     if !disabled("sm2");
@@ -164,23 +182,37 @@ push(@curve_list, @curve_aliases);
 
 my %params_encodings =
     (
-     'named_curve'      => \&supported,
-     'explicit'         => \&unsupported
+     'named_curve'      => \&supported_pass,
+     'explicit'         => \&unsupported_pass
     );
 
 my @output_formats = ('PEM', 'DER');
 
 plan tests => scalar(@curve_list) * scalar(keys %params_encodings)
     * (1 + scalar(@output_formats)) # Try listed @output_formats and text output
+    * 2                             # Test generating parameters and keys
     + 1                             # Checking that with no curve it fails
     + 1                             # Checking that with unknown curve it fails
+    + 1                             # Subtest for explicit only curves
     ;
 
+ok(!run(app([ 'openssl', 'genpkey',
+              '-algorithm', 'EC'])),
+   "genpkey EC with no params should fail");
+
+ok(!run(app([ 'openssl', 'genpkey',
+              '-algorithm', 'EC',
+              '-pkeyopt', 'ec_paramgen_curve:bogus_foobar_curve'])),
+   "genpkey EC with unknown curve name should fail");
+
 foreach my $curvename (@curve_list) {
     foreach my $paramenc (sort keys %params_encodings) {
         my $fn = $params_encodings{$paramenc};
+
+        # --- Test generating parameters ---
+
         $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (text)",
-              app([ 'openssl', 'genpkey',
+              app([ 'openssl', 'genpkey', '-genparam',
                     '-algorithm', 'EC',
                     '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
                     '-pkeyopt', 'ec_param_enc:'.$paramenc,
@@ -196,14 +228,87 @@ foreach my $curvename (@curve_list) {
                         '-outform', $outform,
                         '-out', $outfile]));
         }
+
+        # --- Test generating actual keys ---
+
+        $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (text)",
+              app([ 'openssl', 'genpkey',
+                    '-algorithm', 'EC',
+                    '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
+                    '-pkeyopt', 'ec_param_enc:'.$paramenc,
+                    '-text']));
+
+        foreach my $outform (@output_formats) {
+            my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
+            $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
+                  app([ 'openssl', 'genpkey',
+                        '-algorithm', 'EC',
+                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
+                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
+                        '-outform', $outform,
+                        '-out', $outfile]));
+        }
     }
 }
 
-ok(!run(app([ 'openssl', 'genpkey',
-              '-algorithm', 'EC'])),
-   "genpkey EC with no params should fail");
+subtest "test curves that only support explicit parameters encoding" => sub {
+    plan skip_all => "This test is unsupported under current configuration"
+            if scalar(@explicit_only_curves) <= 0;
 
-ok(!run(app([ 'openssl', 'genpkey',
-              '-algorithm', 'EC',
-              '-pkeyopt', 'ec_paramgen_curve:bogus_foobar_curve'])),
-   "genpkey EC with unknown curve name should fail");
+    plan tests => scalar(@explicit_only_curves) * scalar(keys %params_encodings)
+        * (1 + scalar(@output_formats)) # Try listed @output_formats and text output
+        * 2                             # Test generating parameters and keys
+        ;
+
+    my %params_encodings =
+        (
+         'named_curve'      => \&supported_fail,
+         'explicit'         => \&unsupported_pass
+        );
+
+    foreach my $curvename (@explicit_only_curves) {
+        foreach my $paramenc (sort keys %params_encodings) {
+            my $fn = $params_encodings{$paramenc};
+
+            # --- Test generating parameters ---
+
+            $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (text)",
+                  app([ 'openssl', 'genpkey', '-genparam',
+                        '-algorithm', 'EC',
+                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
+                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
+                        '-text']));
+
+            foreach my $outform (@output_formats) {
+                my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
+                $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
+                      app([ 'openssl', 'genpkey', '-genparam',
+                            '-algorithm', 'EC',
+                            '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
+                            '-pkeyopt', 'ec_param_enc:'.$paramenc,
+                            '-outform', $outform,
+                            '-out', $outfile]));
+            }
+
+            # --- Test generating actual keys ---
+
+            $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (text)",
+                  app([ 'openssl', 'genpkey',
+                        '-algorithm', 'EC',
+                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
+                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
+                        '-text']));
+
+            foreach my $outform (@output_formats) {
+                my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
+                $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
+                      app([ 'openssl', 'genpkey',
+                            '-algorithm', 'EC',
+                            '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
+                            '-pkeyopt', 'ec_param_enc:'.$paramenc,
+                            '-outform', $outform,
+                            '-out', $outfile]));
+            }
+        }
+    }
+};


More information about the openssl-commits mailing list