[openssl] master update

Richard Levitte levitte at openssl.org
Sat Jul 10 15:07:25 UTC 2021


The branch master has been updated
       via  6bfd3e51c04faa97ed98f38e35bd9bb5294b9070 (commit)
       via  50d0a51d6dc83815a6fca5c00c711ffcf407a214 (commit)
       via  f0f4de4e50eaa11eb5a51fa6e7756d4a0876557e (commit)
       via  4cd473518777766e303cebe89c5a056dbec7e513 (commit)
       via  2296cc34f3c700b0bc5c45f35e56641fbb840db3 (commit)
      from  f159b83a75c8d5e5c43ae4b2dec62086a5e36189 (commit)


- Log -----------------------------------------------------------------
commit 6bfd3e51c04faa97ed98f38e35bd9bb5294b9070
Author: Tomas Mraz <tomas at openssl.org>
Date:   Fri Jul 9 15:48:02 2021 +0200

    test_cmp_ctx: Avoid using empty X509 with i2d
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: David von Oheimb <david.von.oheimb at siemens.com>
    (Merged from https://github.com/openssl/openssl/pull/16036)

commit 50d0a51d6dc83815a6fca5c00c711ffcf407a214
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Jul 9 08:51:55 2021 +0200

    Fix test/asn1_encode_test.c to handle encoding/decoding failure
    
    Make it only report (and fail on) encoding/decoding failures when success
    is expected.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16036)

commit f0f4de4e50eaa11eb5a51fa6e7756d4a0876557e
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Jul 9 08:31:24 2021 +0200

    Fix test/asn1_encode_test.c to not use ASN1_FBOOLEAN
    
    ASN1_FBOOLEAN is designed to use as a default for optional ASN1 items.
    This test program used it for non-optional items, which doesn't encode
    well.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16036)

commit 4cd473518777766e303cebe89c5a056dbec7e513
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Jul 8 13:38:45 2021 +0200

    ASN.1: Refuse to encode to DER if non-optional items are missing
    
    Fixes #16026
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16036)

commit 2296cc34f3c700b0bc5c45f35e56641fbb840db3
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Jul 8 13:33:28 2021 +0200

    TEST: Check that i2d refuses to encode non-optional items with no content
    
    The test case creates an RSA public key and tries to pass it through
    i2d_PrivateKey().  This SHOULD fail, since the private bits are missing.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16036)

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

Summary of changes:
 crypto/asn1/tasn_enc.c         | 29 ++++++++++++++-------
 test/asn1_encode_test.c        | 59 +++++++++++++++++++++++-------------------
 test/asn1_internal_test.c      | 44 +++++++++++++++++++++++++++++++
 test/cmp_ctx_test.c            | 22 +++++++++++++---
 test/recipes/65-test_cmp_ctx.t |  6 +++--
 5 files changed, 119 insertions(+), 41 deletions(-)

diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
index 2d24320af9..06473d3411 100644
--- a/crypto/asn1/tasn_enc.c
+++ b/crypto/asn1/tasn_enc.c
@@ -217,7 +217,7 @@ static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
                                 const ASN1_TEMPLATE *tt, int tag, int iclass)
 {
     const int flags = tt->flags;
-    int i, ret, ttag, tclass, ndef;
+    int i, ret, ttag, tclass, ndef, len;
     const ASN1_VALUE *tval;
 
     /*
@@ -303,13 +303,16 @@ static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
         /* Determine total length of items */
         skcontlen = 0;
         for (i = 0; i < sk_const_ASN1_VALUE_num(sk); i++) {
-            int tmplen;
             skitem = sk_const_ASN1_VALUE_value(sk, i);
-            tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
-                                      -1, iclass);
-            if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
+            len = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
+                                   -1, iclass);
+            if (len == -1 || (skcontlen > INT_MAX - len))
+                return -1;
+            if (len == 0 && (tt->flags & ASN1_TFLG_OPTIONAL) == 0) {
+                ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT);
                 return -1;
-            skcontlen += tmplen;
+            }
+            skcontlen += len;
         }
         sklen = ASN1_object_size(ndef, skcontlen, sktag);
         if (sklen == -1)
@@ -347,6 +350,10 @@ static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
         i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
         if (!i)
             return 0;
+        if (i == 0 && (tt->flags & ASN1_TFLG_OPTIONAL) == 0) {
+            ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT);
+            return -1;
+        }
         /* Find length of EXPLICIT tag */
         ret = ASN1_object_size(ndef, i, ttag);
         if (out && ret != -1) {
@@ -360,9 +367,13 @@ static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
     }
 
     /* Either normal or IMPLICIT tagging: combine class and flags */
-    return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
-                            ttag, tclass | iclass);
-
+    len = ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+                              ttag, tclass | iclass);
+    if (len == 0 && (tt->flags & ASN1_TFLG_OPTIONAL) == 0) {
+        ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT);
+        return -1;
+    }
+    return len;
 }
 
 /* Temporary structure used to hold DER encoding of items for SET OF */
diff --git a/test/asn1_encode_test.c b/test/asn1_encode_test.c
index 27f522b222..c453bdf3f8 100644
--- a/test/asn1_encode_test.c
+++ b/test/asn1_encode_test.c
@@ -190,7 +190,7 @@ typedef struct {
 } ASN1_LONG_DATA;
 
 ASN1_SEQUENCE(ASN1_LONG_DATA) = {
-    ASN1_SIMPLE(ASN1_LONG_DATA, success, ASN1_FBOOLEAN),
+    ASN1_SIMPLE(ASN1_LONG_DATA, success, ASN1_BOOLEAN),
     ASN1_SIMPLE(ASN1_LONG_DATA, test_long, LONG),
     ASN1_EXP_OPT(ASN1_LONG_DATA, test_zlong, ZLONG, 0)
 } static_ASN1_SEQUENCE_END(ASN1_LONG_DATA)
@@ -280,7 +280,7 @@ typedef struct {
 } ASN1_INT32_DATA;
 
 ASN1_SEQUENCE(ASN1_INT32_DATA) = {
-    ASN1_SIMPLE(ASN1_INT32_DATA, success, ASN1_FBOOLEAN),
+    ASN1_SIMPLE(ASN1_INT32_DATA, success, ASN1_BOOLEAN),
     ASN1_EMBED(ASN1_INT32_DATA, test_int32, INT32),
     ASN1_EXP_OPT_EMBED(ASN1_INT32_DATA, test_zint32, ZINT32, 0)
 } static_ASN1_SEQUENCE_END(ASN1_INT32_DATA)
@@ -328,7 +328,7 @@ typedef struct {
 } ASN1_UINT32_DATA;
 
 ASN1_SEQUENCE(ASN1_UINT32_DATA) = {
-    ASN1_SIMPLE(ASN1_UINT32_DATA, success, ASN1_FBOOLEAN),
+    ASN1_SIMPLE(ASN1_UINT32_DATA, success, ASN1_BOOLEAN),
     ASN1_EMBED(ASN1_UINT32_DATA, test_uint32, UINT32),
     ASN1_EXP_OPT_EMBED(ASN1_UINT32_DATA, test_zuint32, ZUINT32, 0)
 } static_ASN1_SEQUENCE_END(ASN1_UINT32_DATA)
@@ -376,7 +376,7 @@ typedef struct {
 } ASN1_INT64_DATA;
 
 ASN1_SEQUENCE(ASN1_INT64_DATA) = {
-    ASN1_SIMPLE(ASN1_INT64_DATA, success, ASN1_FBOOLEAN),
+    ASN1_SIMPLE(ASN1_INT64_DATA, success, ASN1_BOOLEAN),
     ASN1_EMBED(ASN1_INT64_DATA, test_int64, INT64),
     ASN1_EXP_OPT_EMBED(ASN1_INT64_DATA, test_zint64, ZINT64, 0)
 } static_ASN1_SEQUENCE_END(ASN1_INT64_DATA)
@@ -425,7 +425,7 @@ typedef struct {
 } ASN1_UINT64_DATA;
 
 ASN1_SEQUENCE(ASN1_UINT64_DATA) = {
-    ASN1_SIMPLE(ASN1_UINT64_DATA, success, ASN1_FBOOLEAN),
+    ASN1_SIMPLE(ASN1_UINT64_DATA, success, ASN1_BOOLEAN),
     ASN1_EMBED(ASN1_UINT64_DATA, test_uint64, UINT64),
     ASN1_EXP_OPT_EMBED(ASN1_UINT64_DATA, test_zuint64, ZUINT64, 0)
 } static_ASN1_SEQUENCE_END(ASN1_UINT64_DATA)
@@ -742,14 +742,17 @@ static int test_intern(const TEST_PACKAGE *package)
                    sizeof(test_custom_data) / sizeof(test_custom_data[0]));
     for (i = 0; i < nelems; i++) {
         size_t pos = i * package->encode_expectations_elem_size;
-        switch (do_encode_custom((EXPECTED *)&((unsigned char *)package
-                                               ->encode_expectations)[pos],
-                                 &test_custom_data[i], package)) {
+        EXPECTED *expected
+            = (EXPECTED *)&((unsigned char *)package->encode_expectations)[pos];
+
+        switch (do_encode_custom(expected, &test_custom_data[i], package)) {
         case -1:
-            TEST_error("Failed custom encode round trip %u of %s",
-                       i, package->name);
-            TEST_openssl_errors();
-            fail++;
+            if (expected->success) {
+                TEST_error("Failed custom encode round trip %u of %s",
+                           i, package->name);
+                TEST_openssl_errors();
+                fail++;
+            }
             break;
         case 0:
             TEST_error("Custom encode round trip %u of %s mismatch",
@@ -763,16 +766,16 @@ static int test_intern(const TEST_PACKAGE *package)
             OPENSSL_die("do_encode_custom() return unknown value",
                         __FILE__, __LINE__);
         }
-        switch (do_decode_custom(&test_custom_data[i],
-                                 (EXPECTED *)&((unsigned char *)package
-                                               ->encode_expectations)[pos],
+        switch (do_decode_custom(&test_custom_data[i], expected,
                                  package->encode_expectations_elem_size,
                                  package)) {
         case -1:
-            TEST_error("Failed custom decode round trip %u of %s",
-                       i, package->name);
-            TEST_openssl_errors();
-            fail++;
+            if (expected->success) {
+                TEST_error("Failed custom decode round trip %u of %s",
+                           i, package->name);
+                TEST_openssl_errors();
+                fail++;
+            }
             break;
         case 0:
             TEST_error("Custom decode round trip %u of %s mismatch",
@@ -792,15 +795,17 @@ static int test_intern(const TEST_PACKAGE *package)
     nelems = package->encdec_data_size / package->encdec_data_elem_size;
     for (i = 0; i < nelems; i++) {
         size_t pos = i * package->encdec_data_elem_size;
-        switch (do_enc_dec((EXPECTED *)&((unsigned char *)package
-                                         ->encdec_data)[pos],
-                           package->encdec_data_elem_size,
-                           package)) {
+        EXPECTED *expected
+            = (EXPECTED *)&((unsigned char *)package->encdec_data)[pos];
+
+        switch (do_enc_dec(expected, package->encdec_data_elem_size, package)) {
         case -1:
-            TEST_error("Failed encode/decode round trip %u of %s",
-                       i, package->name);
-            TEST_openssl_errors();
-            fail++;
+            if (expected->success) {
+                TEST_error("Failed encode/decode round trip %u of %s",
+                           i, package->name);
+                TEST_openssl_errors();
+                fail++;
+            }
             break;
         case 0:
             TEST_error("Encode/decode round trip %u of %s mismatch",
diff --git a/test/asn1_internal_test.c b/test/asn1_internal_test.c
index 5bf0eee8c8..61e4265c8b 100644
--- a/test/asn1_internal_test.c
+++ b/test/asn1_internal_test.c
@@ -9,6 +9,12 @@
 
 /* Internal tests for the asn1 module */
 
+/*
+ * RSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
 #include <stdio.h>
 #include <string.h>
 
@@ -107,6 +113,43 @@ static int test_standard_methods(void)
     return 0;
 }
 
+/**********************************************************************
+ *
+ * Test of that i2d fail on non-existing non-optional items
+ *
+ ***/
+
+#include <openssl/rsa.h>
+
+static int test_empty_nonoptional_content(void)
+{
+    RSA *rsa = NULL;
+    BIGNUM *n = NULL;
+    BIGNUM *e = NULL;
+    int ok = 0;
+
+    if (!TEST_ptr(rsa = RSA_new())
+        || !TEST_ptr(n = BN_new())
+        || !TEST_ptr(e = BN_new())
+        || !TEST_true(RSA_set0_key(rsa, n, e, NULL)))
+        goto end;
+
+    n = e = NULL;                /* They are now "owned" by |rsa| */
+
+    /*
+     * This SHOULD fail, as we're trying to encode a public key as a private
+     * key.  The private key bits MUST be present for a proper RSAPrivateKey.
+     */
+    if (TEST_int_le(i2d_RSAPrivateKey(rsa, NULL), 0))
+        ok = 1;
+
+ end:
+    RSA_free(rsa);
+    BN_free(n);
+    BN_free(e);
+    return ok;
+}
+
 /**********************************************************************
  *
  * Tests of the Unicode code point range
@@ -151,6 +194,7 @@ int setup_tests(void)
 {
     ADD_TEST(test_tbl_standard);
     ADD_TEST(test_standard_methods);
+    ADD_TEST(test_empty_nonoptional_content);
     ADD_TEST(test_unicode_range);
     return 1;
 }
diff --git a/test/cmp_ctx_test.c b/test/cmp_ctx_test.c
index e25aa9ab43..71fa679ff4 100644
--- a/test/cmp_ctx_test.c
+++ b/test/cmp_ctx_test.c
@@ -13,6 +13,11 @@
 
 #include <openssl/x509_vfy.h>
 
+static X509 *test_cert;
+
+/* Avoid using X509_new() via the generic macros below. */
+#define X509_new() X509_dup(test_cert)
+
 typedef struct test_fixture {
     const char *test_case_name;
     OSSL_CMP_CTX *ctx;
@@ -42,7 +47,7 @@ static OSSL_CMP_CTX_TEST_FIXTURE *set_up(const char *const test_case_name)
 static STACK_OF(X509) *sk_X509_new_1(void)
 {
     STACK_OF(X509) *sk = sk_X509_new_null();
-    X509 *x = X509_new();
+    X509 *x = X509_dup(test_cert);
 
     if (x == NULL || !sk_X509_push(sk, x)) {
         sk_X509_free(sk);
@@ -68,12 +73,12 @@ static int execute_CTX_reinit_test(OSSL_CMP_CTX_TEST_FIXTURE *fixture)
     ctx->status = 1;
     ctx->failInfoCode = 1;
     if (!ossl_cmp_ctx_set0_statusString(ctx, sk_ASN1_UTF8STRING_new_null())
-            || !ossl_cmp_ctx_set0_newCert(ctx, X509_new())
+            || !ossl_cmp_ctx_set0_newCert(ctx, X509_dup(test_cert))
             || !TEST_ptr(certs = sk_X509_new_1())
             || !ossl_cmp_ctx_set1_newChain(ctx, certs)
             || !ossl_cmp_ctx_set1_caPubs(ctx, certs)
             || !ossl_cmp_ctx_set1_extraCertsIn(ctx, certs)
-            || !ossl_cmp_ctx_set0_validatedSrvCert(ctx, X509_new())
+            || !ossl_cmp_ctx_set0_validatedSrvCert(ctx, X509_dup(test_cert))
             || !TEST_ptr(bytes = ASN1_OCTET_STRING_new())
             || !OSSL_CMP_CTX_set1_transactionID(ctx, bytes)
             || !OSSL_CMP_CTX_set1_senderNonce(ctx, bytes)
@@ -786,6 +791,17 @@ DEFINE_SET_TEST(ossl_cmp, ctx, 1, 1, recipNonce, ASN1_OCTET_STRING)
 
 int setup_tests(void)
 {
+    char *cert_file;
+
+    if (!test_skip_common_options()) {
+        TEST_error("Error parsing test options\n");
+        return 0;
+    }
+
+    if (!TEST_ptr(cert_file = test_get_argument(0))
+        || !TEST_ptr(test_cert = load_cert_pem(cert_file, NULL)))
+        return 0;
+
     /* OSSL_CMP_CTX_new() is tested by set_up() */
     /* OSSL_CMP_CTX_free() is tested by tear_down() */
     ADD_TEST(test_CTX_reinit);
diff --git a/test/recipes/65-test_cmp_ctx.t b/test/recipes/65-test_cmp_ctx.t
index 93f26ea994..069c0e660b 100644
--- a/test/recipes/65-test_cmp_ctx.t
+++ b/test/recipes/65-test_cmp_ctx.t
@@ -10,7 +10,7 @@
 
 
 use strict;
-use OpenSSL::Test;              # get 'plan'
+use OpenSSL::Test qw/:DEFAULT srctop_file/;
 use OpenSSL::Test::Simple;
 use OpenSSL::Test::Utils;
 
@@ -19,4 +19,6 @@ setup("test_cmp_ctx");
 plan skip_all => "This test is not supported in a no-cmp build"
     if disabled("cmp");
 
-simple_test("test_cmp_ctx", "cmp_ctx_test", "cmp_ctx");
+plan tests => 1;
+
+ok(run(test(["cmp_ctx_test", srctop_file("test", "certs", "ee-cert.pem")])));


More information about the openssl-commits mailing list