[openssl] master update

Matt Caswell matt at openssl.org
Thu Oct 8 11:40:47 UTC 2020


The branch master has been updated
       via  df38dcfcd5c3e264e449589ef0b9fce8ce6e428c (commit)
       via  b565a17d9fc69711813a19723a3f656ae5cd2fc9 (commit)
       via  3861ac3b558a5f4e0cc0285843baeaaeff3fbe4a (commit)
      from  db554ae1104eb5d3279ca338f58a42be61155f2f (commit)


- Log -----------------------------------------------------------------
commit df38dcfcd5c3e264e449589ef0b9fce8ce6e428c
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Oct 1 17:17:58 2020 +0100

    Fix the decoder start type handling
    
    If an explicit decoder start type was provided then it wasn't being
    handled correctly in all cases. Specifically if a PEM start type was
    provided then the decoder would fail.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/13050)

commit b565a17d9fc69711813a19723a3f656ae5cd2fc9
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Oct 1 15:34:24 2020 +0100

    Add a test for encoding and decoding of parameters files
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/13050)

commit 3861ac3b558a5f4e0cc0285843baeaaeff3fbe4a
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Oct 1 15:33:14 2020 +0100

    Fix encoding of DHX parameters files
    
    We were getting confused with DHX parameters and encoding them as PKCS3
    DH parameters instead.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/13050)

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

Summary of changes:
 crypto/encode_decode/decoder_lib.c                 |   2 +-
 .../implementations/encode_decode/encode_key2any.c |  19 +-
 test/endecode_test.c                               | 199 +++++++++++++++++----
 3 files changed, 183 insertions(+), 37 deletions(-)

diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c
index ab7c537038..e44ca8cbd4 100644
--- a/crypto/encode_decode/decoder_lib.c
+++ b/crypto/encode_decode/decoder_lib.c
@@ -259,7 +259,7 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
              * on top of this one, so we don't.
              */
             if (ctx->start_input_type != NULL
-                && strcasecmp(ctx->start_input_type, input_type) != 0)
+                && strcasecmp(ctx->start_input_type, input_type) == 0)
                 continue;
 
             ERR_set_mark();
diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c
index c21b74d9d3..beb487e940 100644
--- a/providers/implementations/encode_decode/encode_key2any.c
+++ b/providers/implementations/encode_decode/encode_key2any.c
@@ -319,12 +319,23 @@ static int dh_priv_to_der(const void *dh, unsigned char **pder)
 
 static int dh_params_to_der_bio(BIO *out, const void *key)
 {
-    return i2d_DHparams_bio(out, key);
+    int type =
+        DH_test_flags(key, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH;
+
+    if (type == EVP_PKEY_DH)
+        return i2d_DHparams_bio(out, key);
+    return i2d_DHxparams_bio(out, key);
 }
 
 static int dh_params_to_pem_bio(BIO *out, const void *key)
 {
-    return PEM_write_bio_DHparams(out, key);
+    int type =
+        DH_test_flags(key, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH;
+
+    if (type == EVP_PKEY_DH)
+        return PEM_write_bio_DHparams(out, key);
+
+    return PEM_write_bio_DHxparams(out, key);
 }
 
 static int dh_check_key_type(const void *key, int expected_type)
@@ -940,8 +951,8 @@ static int key2any_encode_params(struct key2any_ctx_st *ctx,
 #ifndef OPENSSL_NO_DH
 MAKE_ENCODER(dh, dh, EVP_PKEY_DH, der);
 MAKE_ENCODER(dh, dh, EVP_PKEY_DH, pem);
-MAKE_ENCODER(dhx, dh, EVP_PKEY_DH, der);
-MAKE_ENCODER(dhx, dh, EVP_PKEY_DH, pem);
+MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, der);
+MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, pem);
 #endif
 #ifndef OPENSSL_NO_DSA
 MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, der);
diff --git a/test/endecode_test.c b/test/endecode_test.c
index 70258afcc0..b882ff85b1 100644
--- a/test/endecode_test.c
+++ b/test/endecode_test.c
@@ -93,18 +93,21 @@ typedef int (encoder)(void **encoded, long *encoded_len, void *object,
                       const char *output_type, int selection,
                       const char *pass, const char *pcipher);
 typedef int (decoder)(void **object, void *encoded, long encoded_len,
-                      const char *pass);
+                      const char *keytype, const char *input_type,
+                      int selection, const char *pass);
 typedef int (tester)(const void *data1, size_t data1_len,
                      const void *data2, size_t data2_len);
 typedef int (checker)(const char *type, const void *data, size_t data_len);
 typedef void (dumper)(const char *label, const void *data, size_t data_len);
 
+#define FLAG_DECODE_WITH_TYPE   0x0001
+
 static int test_encode_decode(const char *type, EVP_PKEY *pkey,
                               const char *output_type, int selection,
                               const char *pass, const char *pcipher,
                               encoder *encode_cb, decoder *decode_cb,
                               tester *test_cb, checker *check_cb,
-                              dumper *dump_cb)
+                              dumper *dump_cb, int flags)
 {
     void *encoded = NULL;
     long encoded_len = 0;
@@ -118,16 +121,23 @@ static int test_encode_decode(const char *type, EVP_PKEY *pkey,
      * encoding |pkey2| as well.  That last encoding is for checking and
      * dumping purposes.
      */
-    if (!encode_cb(&encoded, &encoded_len, pkey, output_type, selection,
-                   pass, pcipher)
-        || !check_cb(type, encoded, encoded_len)
-        || !decode_cb((void **)&pkey2, encoded, encoded_len, pass)
-        || !encode_cb(&encoded2, &encoded2_len, pkey2, output_type, selection,
-                      pass, pcipher))
+    if (!TEST_true(encode_cb(&encoded, &encoded_len, pkey, output_type,
+                             selection, pass, pcipher))
+        || !TEST_true(check_cb(type, encoded, encoded_len))
+        || !TEST_true(decode_cb((void **)&pkey2, encoded, encoded_len,
+                                (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
+                                output_type, selection, pass))
+        || !TEST_true(encode_cb(&encoded2, &encoded2_len, pkey2, output_type,
+                                selection, pass, pcipher)))
         goto end;
 
-    if (!TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1))
-        goto end;
+    if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
+        if (!TEST_int_eq(EVP_PKEY_parameters_eq(pkey, pkey2), 1))
+            goto end;
+    } else {
+        if (!TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1))
+            goto end;
+    }
 
     /*
      * Double check the encoding, but only for unprotected keys,
@@ -193,25 +203,71 @@ static int encode_EVP_PKEY_prov(void **encoded, long *encoded_len,
 }
 
 static int decode_EVP_PKEY_prov(void **object, void *encoded, long encoded_len,
-                                const char *pass)
+                                const char *keytype, const char *input_type,
+                                int selection, const char *pass)
 {
-    EVP_PKEY *pkey = NULL;
+    EVP_PKEY *pkey = NULL, *testpkey = NULL;
     OSSL_DECODER_CTX *dctx = NULL;
-    BIO *mem_deser = NULL;
+    BIO *encoded_bio = NULL;
     const unsigned char *upass = (const unsigned char *)pass;
     int ok = 0;
+    int i;
+    const char *badtype;
 
-    if (!TEST_ptr(dctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pkey, NULL, NULL,
-                                                          NULL, NULL))
-        || (pass != NULL
-            && !OSSL_DECODER_CTX_set_passphrase(dctx, upass, strlen(pass)))
-        || !TEST_ptr(mem_deser = BIO_new_mem_buf(encoded, encoded_len))
-        || !TEST_true(OSSL_DECODER_from_bio(dctx, mem_deser)))
+    if (strcmp(input_type, "DER") == 0)
+        badtype = "PEM";
+    else
+        badtype = "DER";
+
+    if (!TEST_ptr(encoded_bio = BIO_new_mem_buf(encoded, encoded_len)))
         goto end;
+
+    /*
+     * We attempt the decode 3 times. The first time we provide the expected
+     * starting input type. The second time we provide NULL for the starting
+     * type. The third time we provide a bad starting input type.
+     * The bad starting input type should fail. The other two should succeed
+     * and produce the same result.
+     */
+    for (i = 0; i < 3; i++) {
+        const char *testtype = (i == 0) ? input_type
+                                        : ((i == 1) ? NULL : badtype);
+
+        if (!TEST_ptr(dctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&testpkey,
+                                                              testtype,
+                                                              keytype,
+                                                              NULL, NULL))
+            || (pass != NULL
+                && !OSSL_DECODER_CTX_set_passphrase(dctx, upass, strlen(pass)))
+            || !TEST_int_gt(BIO_reset(encoded_bio), 0)
+               /* We expect to fail when using a bad input type */
+            || !TEST_int_eq(OSSL_DECODER_from_bio(dctx, encoded_bio),
+                            (i == 2) ? 0 : 1))
+            goto end;
+        OSSL_DECODER_CTX_free(dctx);
+        dctx = NULL;
+
+        if (i == 0) {
+            pkey = testpkey;
+            testpkey = NULL;
+        } else if (i == 1) {
+            if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
+                if (!TEST_int_eq(EVP_PKEY_parameters_eq(pkey, testpkey), 1))
+                    goto end;
+            } else {
+                if (!TEST_int_eq(EVP_PKEY_eq(pkey, testpkey), 1))
+                    goto end;
+            }
+        }
+    }
     ok = 1;
     *object = pkey;
+    pkey = NULL;
+
  end:
-    BIO_free(mem_deser);
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_free(testpkey);
+    BIO_free(encoded_bio);
     OSSL_DECODER_CTX_free(dctx);
     return ok;
 }
@@ -433,7 +489,7 @@ static int test_unprotected_via_DER(const char *type, EVP_PKEY *key)
                               NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_mem, check_unprotected_PKCS8_DER,
-                              dump_der);
+                              dump_der, 0);
 }
 
 static int check_unprotected_PKCS8_PEM(const char *type,
@@ -454,7 +510,64 @@ static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key)
                               NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_text, check_unprotected_PKCS8_PEM,
-                              dump_pem);
+                              dump_pem, 0);
+}
+
+static int check_params_DER(const char *type, const void *data, size_t data_len)
+{
+    const unsigned char *datap = data;
+    int ok = 0;
+    int itype = NID_undef;
+    EVP_PKEY *pkey = NULL;
+
+    if (strcmp(type, "DH") == 0)
+        itype = EVP_PKEY_DH;
+    else if (strcmp(type, "X9.42 DH") == 0)
+        itype = EVP_PKEY_DHX;
+    else if (strcmp(type, "DSA") ==  0)
+        itype = EVP_PKEY_DSA;
+    else if (strcmp(type, "EC") ==  0)
+        itype = EVP_PKEY_EC;
+
+    if (itype != NID_undef) {
+        pkey = d2i_KeyParams(itype, NULL, &datap, data_len);
+        ok = (pkey != NULL);
+        EVP_PKEY_free(pkey);
+    }
+
+    return ok;
+}
+
+static int check_params_PEM(const char *type,
+                                       const void *data, size_t data_len)
+{
+    static char expected_pem_header[80];
+
+    return
+        TEST_int_gt(BIO_snprintf(expected_pem_header,
+                                 sizeof(expected_pem_header),
+                                 "-----BEGIN %s PARAMETERS-----", type), 0)
+        && TEST_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
+}
+
+static int test_params_via_DER(const char *type, EVP_PKEY *key)
+{
+    return test_encode_decode(type, key,
+                              "DER", OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              NULL, NULL,
+                              encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+                              test_mem, check_params_DER,
+                              dump_der, FLAG_DECODE_WITH_TYPE);
+}
+
+static int test_params_via_PEM(const char *type, EVP_PKEY *key)
+{
+    return test_encode_decode(type, key,
+                              "PEM", OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              NULL, NULL,
+                              encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+                              test_text, check_params_PEM,
+                              dump_pem, 0);
 }
 
 static int check_unprotected_legacy_PEM(const char *type,
@@ -477,7 +590,7 @@ static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key)
                               NULL, NULL,
                               encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
                               test_text, check_unprotected_legacy_PEM,
-                              dump_pem);
+                              dump_pem, 0);
 }
 
 #ifndef OPENSSL_NO_DSA
@@ -499,7 +612,7 @@ static int test_unprotected_via_MSBLOB(const char *type, EVP_PKEY *key)
                               NULL, NULL,
                               encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
                               test_mem, check_MSBLOB,
-                              dump_der);
+                              dump_der, 0);
 }
 
 # ifndef OPENSSL_NO_RC4
@@ -520,7 +633,7 @@ static int test_unprotected_via_PVK(const char *type, EVP_PKEY *key)
                               NULL, NULL,
                               encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
                               test_mem, check_PVK,
-                              dump_der);
+                              dump_der, 0);
 }
 # endif
 #endif
@@ -547,7 +660,7 @@ static int test_protected_via_DER(const char *type, EVP_PKEY *key)
                               pass, pass_cipher,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_mem, check_protected_PKCS8_DER,
-                              dump_der);
+                              dump_der, 0);
 }
 
 static int check_protected_PKCS8_PEM(const char *type,
@@ -568,7 +681,7 @@ static int test_protected_via_PEM(const char *type, EVP_PKEY *key)
                               pass, pass_cipher,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_text, check_protected_PKCS8_PEM,
-                              dump_pem);
+                              dump_pem, 0);
 }
 
 static int check_protected_legacy_PEM(const char *type,
@@ -592,7 +705,7 @@ static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key)
                               pass, pass_cipher,
                               encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
                               test_text, check_protected_legacy_PEM,
-                              dump_pem);
+                              dump_pem, 0);
 }
 
 #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
@@ -603,7 +716,7 @@ static int test_protected_via_PVK(const char *type, EVP_PKEY *key)
                               | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
                               pass, NULL,
                               encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
-                              test_mem, check_PVK, dump_der);
+                              test_mem, check_PVK, dump_der, 0);
 }
 #endif
 
@@ -624,7 +737,7 @@ static int test_public_via_DER(const char *type, EVP_PKEY *key)
                               | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
                               NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
-                              test_mem, check_public_DER, dump_der);
+                              test_mem, check_public_DER, dump_der, 0);
 }
 
 static int check_public_PEM(const char *type, const void *data, size_t data_len)
@@ -644,7 +757,7 @@ static int test_public_via_PEM(const char *type, EVP_PKEY *key)
                               | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
                               NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
-                              test_text, check_public_PEM, dump_pem);
+                              test_text, check_public_PEM, dump_pem, 0);
 }
 
 #ifndef OPENSSL_NO_DSA
@@ -667,7 +780,7 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
                               NULL, NULL,
                               encode_public_EVP_PKEY_MSBLOB,
                               decode_EVP_PKEY_prov,
-                              test_mem, check_public_MSBLOB, dump_der);
+                              test_mem, check_public_MSBLOB, dump_der, 0);
 }
 #endif
 
@@ -726,6 +839,20 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
     ADD_TEST(test_public_##KEYTYPE##_via_DER);                  \
     ADD_TEST(test_public_##KEYTYPE##_via_PEM)
 
+#define IMPLEMENT_TEST_SUITE_PARAMS(KEYTYPE, KEYTYPEstr)           \
+    static int test_params_##KEYTYPE##_via_DER(void)               \
+    {                                                              \
+        return test_params_via_DER(KEYTYPEstr, key_##KEYTYPE);     \
+    }                                                              \
+    static int test_params_##KEYTYPE##_via_PEM(void)               \
+    {                                                              \
+        return test_params_via_PEM(KEYTYPEstr, key_##KEYTYPE);     \
+    }
+
+#define ADD_TEST_SUITE_PARAMS(KEYTYPE)                          \
+    ADD_TEST(test_params_##KEYTYPE##_via_DER);                  \
+    ADD_TEST(test_params_##KEYTYPE##_via_PEM)
+
 #define IMPLEMENT_TEST_SUITE_LEGACY(KEYTYPE, KEYTYPEstr)                \
     static int test_unprotected_##KEYTYPE##_via_legacy_PEM(void)        \
     {                                                                   \
@@ -777,8 +904,10 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
 #ifndef OPENSSL_NO_DH
 DOMAIN_KEYS(DH);
 IMPLEMENT_TEST_SUITE(DH, "DH")
+IMPLEMENT_TEST_SUITE_PARAMS(DH, "DH")
 DOMAIN_KEYS(DHX);
 IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH")
+IMPLEMENT_TEST_SUITE_PARAMS(DHX, "X9.42 DH")
 /*
  * DH has no support for PEM_write_bio_PrivateKey_traditional(),
  * so no legacy tests.
@@ -787,6 +916,7 @@ IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH")
 #ifndef OPENSSL_NO_DSA
 DOMAIN_KEYS(DSA);
 IMPLEMENT_TEST_SUITE(DSA, "DSA")
+IMPLEMENT_TEST_SUITE_PARAMS(DSA, "DSA")
 IMPLEMENT_TEST_SUITE_LEGACY(DSA, "DSA")
 IMPLEMENT_TEST_SUITE_MSBLOB(DSA, "DSA")
 # ifndef OPENSSL_NO_RC4
@@ -796,6 +926,7 @@ IMPLEMENT_TEST_SUITE_PVK(DSA, "DSA")
 #ifndef OPENSSL_NO_EC
 DOMAIN_KEYS(EC);
 IMPLEMENT_TEST_SUITE(EC, "EC")
+IMPLEMENT_TEST_SUITE_PARAMS(EC, "EC")
 IMPLEMENT_TEST_SUITE_LEGACY(EC, "EC")
 DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
 IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC")
@@ -1101,7 +1232,9 @@ int setup_tests(void)
     if (ok) {
 #ifndef OPENSSL_NO_DH
         ADD_TEST_SUITE(DH);
+        ADD_TEST_SUITE_PARAMS(DH);
         ADD_TEST_SUITE(DHX);
+        ADD_TEST_SUITE_PARAMS(DHX);
         /*
          * DH has no support for PEM_write_bio_PrivateKey_traditional(),
          * so no legacy tests.
@@ -1109,6 +1242,7 @@ int setup_tests(void)
 #endif
 #ifndef OPENSSL_NO_DSA
         ADD_TEST_SUITE(DSA);
+        ADD_TEST_SUITE_PARAMS(DSA);
         ADD_TEST_SUITE_LEGACY(DSA);
         ADD_TEST_SUITE_MSBLOB(DSA);
 # ifndef OPENSSL_NO_RC4
@@ -1117,6 +1251,7 @@ int setup_tests(void)
 #endif
 #ifndef OPENSSL_NO_EC
         ADD_TEST_SUITE(EC);
+        ADD_TEST_SUITE_PARAMS(EC);
         ADD_TEST_SUITE_LEGACY(EC);
         ADD_TEST_SUITE(ECExplicitPrimeNamedCurve);
         ADD_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve);


More information about the openssl-commits mailing list