Fix safestack issues in ssl.h
authorMatt Caswell <matt@openssl.org>
Wed, 2 Sep 2020 15:15:06 +0000 (16:15 +0100)
committerMatt Caswell <matt@openssl.org>
Sun, 13 Sep 2020 10:09:45 +0000 (11:09 +0100)
We fix 3 problems with safestack:
- Including an openssl header file without linking against libcrypto
  can cause compilation failures (even if the app does not otherwise need
  to link against libcrypto). See issue #8102
- Recent changes means that applications in no-deprecated builds will need
  to include additional macro calls in the source code for all stacks that
  they need to use - which is an API break. This changes avoids that
  necessity.
- It is not possible to write code using stacks that works in both a
  no-deprecated and a normal build of OpenSSL. See issue #12707.

Fixes #12707
Contains a partial fix for #8102. A similar PR will be needed for hash to
fully fix.

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12781)

24 files changed:
.gitignore
apps/ciphers.c
apps/s_server.c
build.info
fuzz/client.c
fuzz/server.c
include/openssl/ssl.h.in [moved from include/openssl/ssl.h with 99% similarity]
ssl/d1_srtp.c
ssl/s3_lib.c
ssl/ssl_ciph.c
ssl/ssl_lib.c
ssl/statem/extensions_clnt.c
ssl/statem/extensions_srvr.c
ssl/statem/statem_clnt.c
ssl/statem/statem_lib.c
ssl/statem/statem_srvr.c
ssl/t1_lib.c
test/cipherbytes_test.c
test/cipherlist_test.c
test/ciphername_test.c
test/dtls_mtu_test.c
test/sslcorrupttest.c
test/ssltest_old.c
util/perl/OpenSSL/stackhash.pm [new file with mode: 0644]

index ecbc524829363f9b2afaefebab8c22dd43449dc4..498d3aeffa16f6cd2eeb6aadb5382d7d06c912aa 100644 (file)
@@ -25,6 +25,7 @@
 /include/openssl/configuration.h
 /include/openssl/opensslv.h
 /include/openssl/fipskey.h
+/include/openssl/ssl.h
 
 # Auto generated doc files
 doc/man1/openssl-*.pod
index 380091f16f1b83b3c65e6d95ef5c322909678d7e..500b416046141e424e0aca5c620b0fae614b08f8 100644 (file)
@@ -15,8 +15,6 @@
 #include <openssl/err.h>
 #include <openssl/ssl.h>
 
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
-
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     OPT_STDNAME,
index 4c2e5b27f7d156073dc3e4a0e4382bfab2cacac4..f1ea550fed85d0279ff0e1eaef0499d2b00109dd 100644 (file)
@@ -63,7 +63,6 @@ typedef unsigned int u_int;
 DEFINE_STACK_OF(X509_EXTENSION)
 DEFINE_STACK_OF(X509_CRL)
 DEFINE_STACK_OF(X509)
-DEFINE_STACK_OF(SSL_CIPHER)
 DEFINE_STACK_OF_STRING()
 
 static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
index 1c6787c8008a3b47bdd875c9e11dbe12005969a7..c1933bf73c30708e4f98247318b0d865723d2717 100644 (file)
@@ -15,12 +15,14 @@ DEPEND[libssl]=libcrypto
 # unconditionally before anything else.
 DEPEND[]=include/openssl/configuration.h include/openssl/opensslv.h \
          include/openssl/fipskey.h \
+         include/openssl/ssl.h \
          include/crypto/bn_conf.h include/crypto/dso_conf.h \
          doc/man7/openssl_user_macros.pod
 
 GENERATE[include/openssl/configuration.h]=include/openssl/configuration.h.in
 GENERATE[include/openssl/opensslv.h]=include/openssl/opensslv.h.in
 GENERATE[include/openssl/fipskey.h]=include/openssl/fipskey.h.in
+GENERATE[include/openssl/ssl.h]=include/openssl/ssl.h.in
 GENERATE[include/crypto/bn_conf.h]=include/crypto/bn_conf.h.in
 GENERATE[include/crypto/dso_conf.h]=include/crypto/dso_conf.h.in
 GENERATE[doc/man7/openssl_user_macros.pod]=doc/man7/openssl_user_macros.pod.in
index 01bd70a49f6b255353782e8650fd1f09acaec961..2c2cd90fb848c45c1385978b457a03b21c60ce31 100644 (file)
@@ -20,8 +20,6 @@
 
 #include "rand.inc"
 
-DEFINE_STACK_OF(SSL_COMP)
-
 /* unused, to avoid warning. */
 static int idx;
 
index f00029b0a9ad022c911bc583fbd95d6ffbe93703..8123c90994d62febc93f447a5b5cbc9f68fa5c7c 100644 (file)
@@ -24,8 +24,6 @@
 
 #include "rand.inc"
 
-DEFINE_STACK_OF(SSL_COMP)
-
 static const uint8_t kCertificateDER[] = {
     0x30, 0x82, 0x02, 0xff, 0x30, 0x82, 0x01, 0xe7, 0xa0, 0x03, 0x02, 0x01,
     0x02, 0x02, 0x11, 0x00, 0xb1, 0x84, 0xee, 0x34, 0x99, 0x98, 0x76, 0xfb,
similarity index 99%
rename from include/openssl/ssl.h
rename to include/openssl/ssl.h.in
index 0b17f22193517a08440a6d9deb525487aa4c8447..264b7eddb72b5d7664c713335287e409d2f4bd5b 100644 (file)
@@ -1,4 +1,6 @@
 /*
+ * {- join("\n * ", @autowarntext) -}
+ *
  * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  * Copyright 2005 Nokia. All rights reserved.
@@ -9,6 +11,10 @@
  * https://www.openssl.org/source/license.html
  */
 
+{-
+use OpenSSL::stackhash qw(generate_stack_macros generate_const_stack_macros);
+-}
+
 #ifndef OPENSSL_SSL_H
 # define OPENSSL_SSL_H
 # pragma once
@@ -240,7 +246,9 @@ typedef struct srtp_protection_profile_st {
     const char *name;
     unsigned long id;
 } SRTP_PROTECTION_PROFILE;
-DEFINE_OR_DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
+{-
+    generate_stack_macros("SRTP_PROTECTION_PROFILE");
+-}
 
 
 typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data,
@@ -980,8 +988,10 @@ extern "C" {
  * These need to be after the above set of includes due to a compiler bug
  * in VisualStudio 2015
  */
-DEFINE_OR_DECLARE_STACK_OF(SSL_CIPHER)
-DEFINE_OR_DECLARE_STACK_OF(SSL_COMP)
+{-
+    generate_const_stack_macros("SSL_CIPHER")
+    .generate_stack_macros("SSL_COMP");
+-}
 
 /* compatibility */
 # define SSL_set_app_data(s,arg)         (SSL_set_ex_data(s,0,(char *)(arg)))
index 66c1b54eeb58e666421ffdb3101997b3bdd1f89e..87fb4a243d815f24553b3ed9a8d1cbbc0f0c4845 100644 (file)
@@ -19,8 +19,6 @@
 
 #ifndef OPENSSL_NO_SRTP
 
-DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE)
-
 static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
     {
      "SRTP_AES128_CM_SHA1_80",
index 8f5aaaf94297b78bdbd6dc3e3cf47824d18b550b..c49f2118cae632d30ad718faeea3b77d8bf7ca53 100644 (file)
@@ -22,7 +22,6 @@
 
 DEFINE_STACK_OF(X509_NAME)
 DEFINE_STACK_OF(X509)
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
 
 #define TLS13_NUM_CIPHERS       OSSL_NELEM(tls13_ciphers)
 #define SSL3_NUM_CIPHERS        OSSL_NELEM(ssl3_ciphers)
index 64d773acbde0ff91a1fbb3d252c96d8093670ebe..05add36d4772d73ac36de775c043159661e6b20f 100644 (file)
@@ -25,9 +25,6 @@
 #include "internal/thread_once.h"
 #include "internal/cryptlib.h"
 
-DEFINE_STACK_OF(SSL_COMP)
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
-
 /* NB: make sure indices in these tables match values above */
 
 typedef struct {
index a036ac29e986b724cd2db4240252b52d73fe62c4..139fd628af198dca0868f76676ad94a42f0d5240 100644 (file)
 
 DEFINE_STACK_OF(X509)
 DEFINE_STACK_OF(X509_NAME)
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
 DEFINE_STACK_OF(X509_EXTENSION)
 DEFINE_STACK_OF(OCSP_RESPID)
-DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE)
 DEFINE_STACK_OF(SCT)
 
 static int ssl_undefined_function_1(SSL *ssl, SSL3_RECORD *r, size_t s, int t,
index abff069ec9727c6d96e71aca2f46ef5827a17b48..f8ae0612e3ab8c76231e21c4d3f9288b1fea0b3a 100644 (file)
@@ -12,8 +12,6 @@
 #include "internal/cryptlib.h"
 #include "statem_local.h"
 
-DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE)
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
 DEFINE_STACK_OF(OCSP_RESPID)
 
 EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt,
index b5cd34b646260590b7cee4f777b48a9de788672e..c686d00f0e6a8059242868d4eae3366fb46843ab 100644 (file)
@@ -12,7 +12,6 @@
 #include "statem_local.h"
 #include "internal/cryptlib.h"
 
-DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE)
 DEFINE_STACK_OF(OCSP_RESPID)
 DEFINE_STACK_OF(X509_EXTENSION)
 
index 0780e5fc9a3ed09e1e97415b0b6d38a22d8c26ef..f8a3d25c0801bfc34b4014fb7f81817a15302aa7 100644 (file)
@@ -29,8 +29,6 @@
 #include <internal/cryptlib.h>
 
 DEFINE_STACK_OF(X509)
-DEFINE_STACK_OF(SSL_COMP)
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
 
 static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt);
 static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt);
index e0ff00d1b80f4ed434b00cbe2f65ed0e5254b1d0..79195b2aa2070afd57f98bbe43724c3235d5473c 100644 (file)
@@ -23,7 +23,6 @@
 
 DEFINE_STACK_OF(X509)
 DEFINE_STACK_OF(X509_NAME)
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
 
 /*
  * Map error codes to TLS/SSL alart types.
index c46254c85862d144bb22f4b70777032e67742e33..f42e7865ebbb56a9ec4e68008d19ba3bf6e93c00 100644 (file)
@@ -27,8 +27,6 @@
 #include <openssl/asn1t.h>
 
 DEFINE_STACK_OF(X509)
-DEFINE_STACK_OF(SSL_COMP)
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
 
 #define TICKET_NONCE_SIZE       8
 
index bf955bf3ec7ac2b2ef61d81a403c45cbd1441b19..702622487f99ce9c6798f51ad5b1546a0af8539e 100644 (file)
@@ -28,7 +28,6 @@
 #include "ssl_local.h"
 #include <openssl/ct.h>
 
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
 DEFINE_STACK_OF(X509)
 DEFINE_STACK_OF(X509_NAME)
 
index cbbfff2a417569bd09a16b6ca1252dc5b047d418..ed4eacbdf356b6fd294c0dab577bd8d3c11eb0ba 100644 (file)
@@ -21,8 +21,6 @@
 #include "internal/nelem.h"
 #include "testutil.h"
 
-DEFINE_STACK_OF(SSL_CIPHER)
-
 static SSL_CTX *ctx;
 static SSL *s;
 
index 0f337b40546b999d377eef2a73a36b61b5cbd346..380f0727fc5af1604971b7ee7b1e5698206d0b11 100644 (file)
@@ -21,8 +21,6 @@
 #include "internal/nelem.h"
 #include "testutil.h"
 
-DEFINE_STACK_OF_CONST(SSL_CIPHER)
-
 typedef struct cipherlist_test_fixture {
     const char *test_case_name;
     SSL_CTX *server;
index c82a1648277aeed3af32182deb50d38b1033d613..c4ec6cadd740bb4b8739526f775f45e8c274b753 100644 (file)
@@ -22,8 +22,6 @@
 #include "internal/nelem.h"
 #include "testutil.h"
 
-DEFINE_STACK_OF(SSL_CIPHER)
-
 typedef struct cipher_id_name {
     int id;
     const char *name;
index b0730077b713523ec4d2a66d1428f70515c158a9..588ca32c79f51ab67e2bb888bc65077093097715 100644 (file)
@@ -20,8 +20,6 @@
 /* for SSL_READ_ETM() */
 #include "../ssl/ssl_local.h"
 
-DEFINE_STACK_OF(SSL_CIPHER)
-
 static int debug = 0;
 
 static unsigned int clnt_psk_callback(SSL *ssl, const char *hint,
index 641ecf331de95203c2551aaedba1c7e1cf74fbcd..ca9e8bfd731a9c5fb965442dfe17fa21b48c25df 100644 (file)
@@ -11,8 +11,6 @@
 #include "ssltestlib.h"
 #include "testutil.h"
 
-DEFINE_STACK_OF(SSL_CIPHER)
-
 static int docorrupt = 0;
 
 static void copy_flags(BIO *bio)
index 4f340fc2e0dca9c8c2173a3c6057a4fdd2dae085..88aef5e8963d6983abcfe7ba5b20b87cd77010cd 100644 (file)
@@ -81,7 +81,6 @@
 # include <unistd.h>
 #endif
 
-DEFINE_STACK_OF(SSL_COMP)
 DEFINE_STACK_OF_STRING()
 
 static SSL_CTX *s_ctx = NULL;
diff --git a/util/perl/OpenSSL/stackhash.pm b/util/perl/OpenSSL/stackhash.pm
new file mode 100644 (file)
index 0000000..d8ca76a
--- /dev/null
@@ -0,0 +1,92 @@
+#! /usr/bin/env perl
+# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+package OpenSSL::stackhash;
+
+use strict;
+use warnings;
+
+require Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT_OK = qw(generate_stack_macros generate_const_stack_macros);
+
+sub generate_stack_macros_int {
+    my $nametype = shift;
+    my $realtype = shift;
+    my $plaintype = shift;
+
+    my $macros = <<END_MACROS;
+STACK_OF(${nametype});
+typedef int (*sk_${nametype}_compfunc)(const ${plaintype} * const *a, const ${plaintype} *const *b);
+typedef void (*sk_${nametype}_freefunc)(${plaintype} *a);
+typedef ${plaintype} * (*sk_${nametype}_copyfunc)(const ${plaintype} *a);
+static ossl_unused ossl_inline ${realtype} *ossl_check_${nametype}_type(${realtype} *ptr)
+{
+    return ptr;
+}
+static ossl_unused ossl_inline const OPENSSL_STACK *ossl_check_const_${nametype}_sk_type(const STACK_OF(${nametype}) *sk)
+{
+    return (const OPENSSL_STACK *)sk;
+}
+static ossl_unused ossl_inline OPENSSL_STACK *ossl_check_${nametype}_sk_type(STACK_OF(${nametype}) *sk)
+{
+    return (OPENSSL_STACK *)sk;
+}
+static ossl_unused ossl_inline OPENSSL_sk_compfunc ossl_check_${nametype}_compfunc_type(sk_${nametype}_compfunc cmp)
+{
+    return (OPENSSL_sk_compfunc)cmp;
+}
+static ossl_unused ossl_inline OPENSSL_sk_copyfunc ossl_check_${nametype}_copyfunc_type(sk_${nametype}_copyfunc cpy)
+{
+    return (OPENSSL_sk_copyfunc)cpy;
+}
+static ossl_unused ossl_inline OPENSSL_sk_freefunc ossl_check_${nametype}_freefunc_type(sk_${nametype}_freefunc fr)
+{
+    return (OPENSSL_sk_freefunc)fr;
+}
+#define sk_${nametype}_num(sk) OPENSSL_sk_num(ossl_check_const_${nametype}_sk_type(sk))
+#define sk_${nametype}_value(sk, idx) ((${realtype} *)OPENSSL_sk_value(ossl_check_const_${nametype}_sk_type(sk), (idx)))
+#define sk_${nametype}_new(cmp) ((STACK_OF(${nametype}) *)OPENSSL_sk_new(ossl_check_${nametype}_compfunc_type(cmp)))
+#define sk_${nametype}_new_null() ((STACK_OF(${nametype}) *)OPENSSL_sk_new_null())
+#define sk_${nametype}_new_reserve(cmp, n) ((STACK_OF(${nametype}) *)OPENSSL_sk_new_reserve(ossl_check_${nametype}_compfunc_type(cmp), (n)))
+#define sk_${nametype}_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_${nametype}_sk_type(sk), (n))
+#define sk_${nametype}_free(sk) OPENSSL_sk_free(ossl_check_${nametype}_sk_type(sk))
+#define sk_${nametype}_zero(sk) OPENSSL_sk_zero(ossl_check_${nametype}_sk_type(sk))
+#define sk_${nametype}_delete(sk, i) ((${realtype} *)OPENSSL_sk_delete(ossl_check_${nametype}_sk_type(sk), (i)))
+#define sk_${nametype}_delete_ptr(sk, ptr) ((${realtype} *)OPENSSL_sk_delete_ptr(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr)))
+#define sk_${nametype}_push(sk, ptr) OPENSSL_sk_push(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr))
+#define sk_${nametype}_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr))
+#define sk_${nametype}_pop(sk) ((${realtype} *)OPENSSL_sk_pop(ossl_check_${nametype}_sk_type(sk)))
+#define sk_${nametype}_shift(sk) ((${realtype} *)OPENSSL_sk_shift(ossl_check_${nametype}_sk_type(sk)))
+#define sk_${nametype}_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_${nametype}_sk_type(sk),ossl_check_${nametype}_freefunc_type(freefunc))
+#define sk_${nametype}_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr), (idx))
+#define sk_${nametype}_set(sk, idx, ptr) ((${realtype} *)OPENSSL_sk_set(ossl_check_${nametype}_sk_type(sk), (idx), ossl_check_${nametype}_type(ptr)))
+#define sk_${nametype}_find(sk, ptr) OPENSSL_sk_find(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr))
+#define sk_${nametype}_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr))
+#define sk_${nametype}_sort(sk) OPENSSL_sk_sort(ossl_check_${nametype}_sk_type(sk))
+#define sk_${nametype}_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_${nametype}_sk_type(sk))
+#define sk_${nametype}_dup(sk) ((STACK_OF(${nametype}) *)OPENSSL_sk_dup(ossl_check_const_${nametype}_sk_type(sk)))
+#define sk_${nametype}_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(${nametype}) *)OPENSSL_sk_deep_copy(ossl_check_const_${nametype}_sk_type(sk), ossl_check_${nametype}_copyfunc_type(copyfunc), ossl_check_${nametype}_freefunc_type(freefunc)))
+#define sk_${nametype}_set_cmp_func(sk, cmp) ((sk_${nametype}_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_compfunc_type(cmp)))
+END_MACROS
+
+    return $macros;
+}
+
+sub generate_stack_macros {
+    my $type = shift;
+
+    return generate_stack_macros_int($type, $type, $type);
+}
+
+sub generate_const_stack_macros {
+    my $type = shift;
+
+    return generate_stack_macros_int($type, "const $type", $type);
+}
+1;