diff options
author | Eduardo Chappa <chappa@washington.edu> | 2016-09-03 18:44:40 -0600 |
---|---|---|
committer | Eduardo Chappa <chappa@washington.edu> | 2016-09-03 18:44:40 -0600 |
commit | be296fed0db493bd09c0ffd4ee67e8687eb69c1d (patch) | |
tree | aa64a53975e17167c11209cb2fdaeb3addbc2c60 | |
parent | 7663f0dd87d15a7b53b81aecef8aaf5efd100d3f (diff) | |
download | alpine-be296fed0db493bd09c0ffd4ee67e8687eb69c1d.tar.xz |
* Alpine does not build with openssl 1.1.0, so this update fixes that.
Users have the option to build with older versions of OpenSSL or with
version 1.1.0. The current code is transitional and it is intended
that we will move Alpine to build exclusively with version 1.1.0 or
above in the future. This update also recognizes if we are using
LibreSSL. It was tested with version 2.4.2.
-rw-r--r-- | alpine/smime.c | 148 | ||||
-rwxr-xr-x | configure | 386 | ||||
-rw-r--r-- | configure.ac | 106 | ||||
-rw-r--r-- | imap/src/osdep/unix/ssl_unix.c | 83 | ||||
-rw-r--r-- | pith/pine.hlp | 2 | ||||
-rw-r--r-- | pith/smime.c | 8 | ||||
-rw-r--r-- | pith/smkeys.c | 39 | ||||
-rw-r--r-- | pith/smkeys.h | 13 | ||||
-rw-r--r-- | po/Makefile.in | 2 |
9 files changed, 631 insertions, 156 deletions
diff --git a/alpine/smime.c b/alpine/smime.c index 7a4fde97..2eb58588 100644 --- a/alpine/smime.c +++ b/alpine/smime.c @@ -381,93 +381,79 @@ output_cert_info(X509 *cert, gf_io_t pc) gf_set_so_writec(&spc, left); - if(!cert->cert_info){ - gf_puts("Couldn't find certificate info.", spc); - gf_puts(NEWLINE, spc); - } - else{ - gf_puts_uline("Certificate Owner", spc); - gf_puts(NEWLINE, spc); - - output_X509_NAME(cert->cert_info->subject, spc); - gf_puts(NEWLINE, spc); - - gf_puts_uline("Serial Number", spc); - gf_puts(NEWLINE, spc); - - { - ASN1_INTEGER *bs; - long l; - const char *neg; - int i; - - bs = X509_get_serialNumber(cert); - if (bs->length <= (int)sizeof(long)){ - l = ASN1_INTEGER_get(bs); - if (bs->type == V_ASN1_NEG_INTEGER){ - l = -l; - neg="-"; - } - else - neg=""; - snprintf(buf, sizeof(buf), " %s%lu (%s0x%lx)", neg, l, neg, l); - } else { - snprintf(buf, sizeof(buf), "%s", bs->type == V_ASN1_NEG_INTEGER ? "(Negative)" : ""); - for (i = 0; i < bs->length; i++) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%02x%s", bs->data[i], - i+1 == bs->length ? "" : ":"); - } + gf_puts_uline("Certificate Owner", spc); + gf_puts(NEWLINE, spc); + + output_X509_NAME(X509_get_subject_name(cert), spc); + gf_puts(NEWLINE, spc); + + gf_puts_uline("Serial Number", spc); + gf_puts(NEWLINE, spc); + + { ASN1_INTEGER *bs; + long l; + const char *neg; + int i; + + bs = X509_get_serialNumber(cert); + if (bs->length <= (int)sizeof(long)){ + l = ASN1_INTEGER_get(bs); + if (bs->type == V_ASN1_NEG_INTEGER){ + l = -l; + neg="-"; + } + else + neg=""; + snprintf(buf, sizeof(buf), " %s%lu (%s0x%lx)", neg, l, neg, l); + } else { + snprintf(buf, sizeof(buf), "%s", bs->type == V_ASN1_NEG_INTEGER ? "(Negative)" : ""); + for (i = 0; i < bs->length; i++) + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%02x%s", bs->data[i], + i+1 == bs->length ? "" : ":"); } - gf_puts(buf, spc); - gf_puts(NEWLINE, spc); - gf_puts(NEWLINE, spc); - - gf_puts_uline("Validity", spc); - gf_puts(NEWLINE, spc); - { - BIO *mb = BIO_new(BIO_s_mem()); - char iobuf[4096]; + } + gf_puts(buf, spc); + gf_puts(NEWLINE, spc); + gf_puts(NEWLINE, spc); + + gf_puts_uline("Validity", spc); + gf_puts(NEWLINE, spc); + { BIO *mb = BIO_new(BIO_s_mem()); + char iobuf[4096]; - gf_puts("Not Before: ", spc); + gf_puts("Not Before: ", spc); - (void) BIO_reset(mb); - ASN1_UTCTIME_print(mb, cert->cert_info->validity->notBefore); - (void) BIO_flush(mb); - while((len = BIO_read(mb, iobuf, sizeof(iobuf))) > 0) - gf_nputs(iobuf, len, spc); + (void) BIO_reset(mb); + ASN1_UTCTIME_print(mb, X509_get0_notBefore(cert)); + (void) BIO_flush(mb); + while((len = BIO_read(mb, iobuf, sizeof(iobuf))) > 0) + gf_nputs(iobuf, len, spc); - gf_puts(NEWLINE, spc); + gf_puts(NEWLINE, spc); - gf_puts("Not After: ", spc); + gf_puts("Not After: ", spc); - (void) BIO_reset(mb); - ASN1_UTCTIME_print(mb, cert->cert_info->validity->notAfter); - (void) BIO_flush(mb); - while((len = BIO_read(mb, iobuf, sizeof(iobuf))) > 0) - gf_nputs(iobuf, len, spc); + (void) BIO_reset(mb); + ASN1_UTCTIME_print(mb, X509_get0_notAfter(cert)); + (void) BIO_flush(mb); + while((len = BIO_read(mb, iobuf, sizeof(iobuf))) > 0) + gf_nputs(iobuf, len, spc); - gf_puts(NEWLINE, spc); - gf_puts(NEWLINE, spc); + gf_puts(NEWLINE, spc); + gf_puts(NEWLINE, spc); - BIO_free(mb); - } + BIO_free(mb); } gf_clear_so_writec(left); gf_set_so_writec(&spc, right); - if(!cert->cert_info){ - gf_puts(_("Couldn't find certificate info."), spc); - gf_puts(NEWLINE, spc); - } - else{ - gf_puts_uline("Issuer", spc); - gf_puts(NEWLINE, spc); + gf_puts_uline("Issuer", spc); + gf_puts(NEWLINE, spc); - output_X509_NAME(cert->cert_info->issuer, spc); - gf_puts(NEWLINE, spc); - } + output_X509_NAME(X509_get_issuer_name(cert), spc); + gf_puts(NEWLINE, spc); gf_clear_so_writec(right); @@ -494,6 +480,7 @@ output_cert_info(X509 *cert, gf_io_t pc) X509_NAME_ENTRY *e; int i, offset = 2; char space[256]; + X509_NAME *subject; for(i = 0; i < offset; i++) space[i] = ' '; @@ -502,7 +489,7 @@ output_cert_info(X509 *cert, gf_io_t pc) x = i == -1 ? cert : sk_X509_value(chain, i); - if(x && x->cert_info){ + if(x){ if(i>=0){ space[offset + i + 0] = ' '; space[offset + i + 1] = '\\'; @@ -520,11 +507,10 @@ output_cert_info(X509 *cert, gf_io_t pc) else gf_puts_uline("Issued to: ", pc); - e = X509_NAME_get_entry(x->cert_info->subject, - X509_NAME_entry_count(x->cert_info->subject)-1); + subject = X509_get_subject_name(x); - if(e){ - X509_NAME_get_text_by_OBJ(x->cert_info->subject, e->object, buf, sizeof(buf)); + if((e = X509_NAME_get_entry(subject, X509_NAME_entry_count(subject)-1)) != NULL){ + X509_NAME_get_text_by_OBJ(subject, X509_NAME_ENTRY_get_object(e), buf, sizeof(buf)); gf_puts(buf, pc); gf_puts(NEWLINE, pc); } @@ -535,10 +521,10 @@ output_cert_info(X509 *cert, gf_io_t pc) break; } } - e = X509_NAME_get_entry(x->cert_info->issuer, - X509_NAME_entry_count(x->cert_info->issuer)-1); + e = X509_NAME_get_entry(X509_get_issuer_name(x), + X509_NAME_entry_count(X509_get_issuer_name(x))-1); if(e){ - X509_NAME_get_text_by_OBJ(x->cert_info->issuer, e->object, buf, sizeof(buf)); + X509_NAME_get_text_by_OBJ(X509_get_issuer_name(x), X509_NAME_ENTRY_get_object(e), buf, sizeof(buf)); space[offset + i + 0] = ' '; space[offset + i + 1] = '\\'; space[offset + i + 2] = '-'; @@ -573,7 +559,7 @@ output_X509_NAME(X509_NAME *name, gf_io_t pc) if(!e) continue; - X509_NAME_get_text_by_OBJ(name, e->object, buf, sizeof(buf)); + X509_NAME_get_text_by_OBJ(name, X509_NAME_ENTRY_get_object(e), buf, sizeof(buf)); gf_puts(buf, pc); gf_puts(NEWLINE, pc); @@ -18235,6 +18235,47 @@ if test "x$alpine_DL" = "xnone" ; then fi if test "x$alpine_SSLTYPE" != "xnone" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if OpenSSL is LibreSSL" >&5 +$as_echo_n "checking if OpenSSL is LibreSSL... " >&6; } + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 +$as_echo "$as_me: WARNING: cross compiling: not checking" >&2;} +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdio.h> +#include <stdlib.h> +#if HAVE_STDINT_H +#include <stdint.h> +#endif /* HAVE_STDINT_H */ +#include <openssl/ssl.h> +int main(void) { + + if (LIBRESSL_VERSION_NUMBER >= 0x20000000L) + exit(0); + + exit(2); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + alpine_SSLPROVIDER="libressl" + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi + +if test "x$alpine_SSLTYPE" != "xnone" -a "x$alpine_SSLPROVIDER" != "xlibressl" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking Openssl library version >= 1.0.0c" >&5 $as_echo_n "checking Openssl library version >= 1.0.0c... " >&6; } if test "$cross_compiling" = yes; then : @@ -18252,7 +18293,7 @@ else #include <openssl/ssl.h> int main(void) { - if (OPENSSL_VERSION_NUMBER >= 0x1000003f) + if (OPENSSL_VERSION_NUMBER >= 0x1000003fL) exit(0); exit(2); @@ -18262,6 +18303,8 @@ _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } + alpine_SSLPROVIDER="openssl" + else alpine_SSLTYPE="none" fi @@ -18274,7 +18317,179 @@ fi as_fn_error $? "Install openssl version >= 1.0.0c" "$LINENO" 5 exit 1 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing TLSv1_2_client_method" >&5 +fi + +if test "x$alpine_SSLTYPE" != "xnone" -a "x$alpine_SSLPROVIDER" != "xlibressl" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking Openssl library version >= 1.1.0" >&5 +$as_echo_n "checking Openssl library version >= 1.1.0... " >&6; } + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 +$as_echo "$as_me: WARNING: cross compiling: not checking" >&2;} +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdio.h> +#include <stdlib.h> +#if HAVE_STDINT_H +#include <stdint.h> +#endif /* HAVE_STDINT_H */ +#include <openssl/ssl.h> +int main(void) { + + if (OPENSSL_VERSION_NUMBER >= 0x10100000L) + exit(0); + + exit(2); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + alpine_SSLVERSION="new" + CFLAGS="$CFLAGS -DOPENSSL_1_1_0 -DOPENSSL_API_COMPAT=0x10100000L" + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + alpine_SSLVERSION="old" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi + +if test "x$alpine_SSLTYPE" != "xnone" ; then + if test "x$alpine_SSLVERSION" = "xold" -o "x$alpine_SSLPROVIDER" = "xlibressl" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSLeay" >&5 +$as_echo_n "checking for library containing SSLeay... " >&6; } +if ${ac_cv_search_SSLeay+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char SSLeay (); +int +main () +{ +return SSLeay (); + ; + return 0; +} +_ACEOF +for ac_lib in '' crypto; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_SSLeay=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_SSLeay+:} false; then : + break +fi +done +if ${ac_cv_search_SSLeay+:} false; then : + +else + ac_cv_search_SSLeay=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSLeay" >&5 +$as_echo "$ac_cv_search_SSLeay" >&6; } +ac_res=$ac_cv_search_SSLeay +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + alpine_CRYPTO="none" +fi + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing OpenSSL_version_num" >&5 +$as_echo_n "checking for library containing OpenSSL_version_num... " >&6; } +if ${ac_cv_search_OpenSSL_version_num+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char OpenSSL_version_num (); +int +main () +{ +return OpenSSL_version_num (); + ; + return 0; +} +_ACEOF +for ac_lib in '' crypto; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_OpenSSL_version_num=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_OpenSSL_version_num+:} false; then : + break +fi +done +if ${ac_cv_search_OpenSSL_version_num+:} false; then : + +else + ac_cv_search_OpenSSL_version_num=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_OpenSSL_version_num" >&5 +$as_echo "$ac_cv_search_OpenSSL_version_num" >&6; } +ac_res=$ac_cv_search_OpenSSL_version_num +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + alpine_CRYPTO="none" +fi + + fi + if test "x$alpine_CRYPTO" = "xnone" ; then + as_fn_error $? "crypto library NOT found" "$LINENO" 5 + exit 1 + fi +fi + +if test "x$alpine_SSLTYPE" != "xnone" ; then + if test "x$alpine_SSLVERSION" = "xold" -o "x$alpine_SSLPROVIDER" = "xlibressl" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing TLSv1_2_client_method" >&5 $as_echo_n "checking for library containing TLSv1_2_client_method... " >&6; } if ${ac_cv_search_TLSv1_2_client_method+:} false; then : $as_echo_n "(cached) " >&6 @@ -18334,12 +18549,68 @@ $as_echo "#define SSL_SUPPORTS_TLSV1_2 1" >>confdefs.h fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing TLS_client_method" >&5 +$as_echo_n "checking for library containing TLS_client_method... " >&6; } +if ${ac_cv_search_TLS_client_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char TLS_client_method (); +int +main () +{ +return TLS_client_method (); + ; + return 0; +} +_ACEOF +for ac_lib in '' ssl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_TLS_client_method=$ac_res fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_TLS_client_method+:} false; then : + break +fi +done +if ${ac_cv_search_TLS_client_method+:} false; then : -if test "x$alpine_SSLTYPE" != "xnone" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSLeay" >&5 -$as_echo_n "checking for library containing SSLeay... " >&6; } -if ${ac_cv_search_SSLeay+:} false; then : +else + ac_cv_search_TLS_client_method=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_TLS_client_method" >&5 +$as_echo "$ac_cv_search_TLS_client_method" >&6; } +ac_res=$ac_cv_search_TLS_client_method +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + alpine_SSLTYPE="none" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing DTLS_client_method" >&5 +$as_echo_n "checking for library containing DTLS_client_method... " >&6; } +if ${ac_cv_search_DTLS_client_method+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -18352,16 +18623,16 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char SSLeay (); +char DTLS_client_method (); int main () { -return SSLeay (); +return DTLS_client_method (); ; return 0; } _ACEOF -for ac_lib in '' crypto; do +for ac_lib in '' ssl; do if test -z "$ac_lib"; then ac_res="none required" else @@ -18369,40 +18640,43 @@ for ac_lib in '' crypto; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_SSLeay=$ac_res + ac_cv_search_DTLS_client_method=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if ${ac_cv_search_SSLeay+:} false; then : + if ${ac_cv_search_DTLS_client_method+:} false; then : break fi done -if ${ac_cv_search_SSLeay+:} false; then : +if ${ac_cv_search_DTLS_client_method+:} false; then : else - ac_cv_search_SSLeay=no + ac_cv_search_DTLS_client_method=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSLeay" >&5 -$as_echo "$ac_cv_search_SSLeay" >&6; } -ac_res=$ac_cv_search_SSLeay +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_DTLS_client_method" >&5 +$as_echo "$ac_cv_search_DTLS_client_method" >&6; } +ac_res=$ac_cv_search_DTLS_client_method if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else - alpine_CRYPTO="none" + alpine_SSLTYPE="none" fi - if test "x$alpine_CRYPTO" = "xnone" ; then - as_fn_error $? "crypto library NOT found" "$LINENO" 5 - exit 1 - fi + if test "x$alpine_SSLTYPE" != "xnone" ; then + +$as_echo "#define SSL_SUPPORTS_TLSV1_2 1" >>confdefs.h + + fi + fi fi if test "x$alpine_SSLTYPE" != "xnone" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_library_init" >&5 + if test "x$alpine_SSLVERSION" = "xold" -o "x$alpine_SSLPROVIDER" = "xlibressl" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_library_init" >&5 $as_echo_n "checking for library containing SSL_library_init... " >&6; } if ${ac_cv_search_SSL_library_init+:} false; then : $as_echo_n "(cached) " >&6 @@ -18460,12 +18734,74 @@ else alpine_SSLTYPE="none" fi + if test "x$alpine_SSLTYPE" = "xnone" ; then + as_fn_error $? "No library containing SSL_library_init found in your path" "$LINENO" 5 + exit 1 + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing OPENSSL_init_ssl" >&5 +$as_echo_n "checking for library containing OPENSSL_init_ssl... " >&6; } +if ${ac_cv_search_OPENSSL_init_ssl+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - if test "x$alpine_SSLTYPE" = "xnone" ; then - as_fn_error $? "No library containing SSL_library_init found in your path" "$LINENO" 5 - exit 1 +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char OPENSSL_init_ssl (); +int +main () +{ +return OPENSSL_init_ssl (); + ; + return 0; +} +_ACEOF +for ac_lib in '' ssl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_OPENSSL_init_ssl=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_OPENSSL_init_ssl+:} false; then : + break +fi +done +if ${ac_cv_search_OPENSSL_init_ssl+:} false; then : +else + ac_cv_search_OPENSSL_init_ssl=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_OPENSSL_init_ssl" >&5 +$as_echo "$ac_cv_search_OPENSSL_init_ssl" >&6; } +ac_res=$ac_cv_search_OPENSSL_init_ssl +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + alpine_SSLTYPE="none" +fi + + if test "x$alpine_SSLTYPE" = "xnone" ; then + as_fn_error $? "No library containing OPENSSL_init_ssl found in your path" "$LINENO" 5 + exit 1 + fi + fi fi if test "$alpine_with_ldap" = "yes" ; then diff --git a/configure.ac b/configure.ac index 94b062d4..fafa819c 100644 --- a/configure.ac +++ b/configure.ac @@ -1355,8 +1355,35 @@ if test "x$alpine_DL" = "xnone" ; then exit 1 fi -dnl Check Openssl/LibreSSL version first +dnl Check if openssl = LibreSSL if test "x$alpine_SSLTYPE" != "xnone" ; then + AC_MSG_CHECKING([if OpenSSL is LibreSSL]) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include <stdio.h> +#include <stdlib.h> +#if HAVE_STDINT_H +#include <stdint.h> +#endif /* HAVE_STDINT_H */ +#include <openssl/ssl.h> +int main(void) { + + if (LIBRESSL_VERSION_NUMBER >= 0x20000000L) + exit(0); + + exit(2); +} + ]])], + [ AC_MSG_RESULT(yes) + alpine_SSLPROVIDER="libressl" + ], + [ AC_MSG_RESULT(no) + ], + [ AC_MSG_WARN([cross compiling: not checking])]) +fi + +dnl Check Openssl/LibreSSL version first +if test "x$alpine_SSLTYPE" != "xnone" -a "x$alpine_SSLPROVIDER" != "xlibressl" ; then AC_MSG_CHECKING([Openssl library version >= 1.0.0c]) AC_RUN_IFELSE( [AC_LANG_SOURCE([[ @@ -1368,13 +1395,15 @@ if test "x$alpine_SSLTYPE" != "xnone" ; then #include <openssl/ssl.h> int main(void) { - if (OPENSSL_VERSION_NUMBER >= 0x1000003f) + if (OPENSSL_VERSION_NUMBER >= 0x1000003fL) exit(0); exit(2); } ]])], - [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(yes) + alpine_SSLPROVIDER="openssl" + ], [ alpine_SSLTYPE="none" ], [ AC_MSG_WARN([cross compiling: not checking])]) @@ -1382,30 +1411,79 @@ int main(void) { AC_MSG_ERROR(Install openssl version >= 1.0.0c) exit 1 fi - AC_SEARCH_LIBS(TLSv1_2_client_method,ssl, - [ alpine_c_client_cflags="$alpine_c_client_cflags -DTLSV1_2" - AC_DEFINE([SSL_SUPPORTS_TLSV1_2], [1], [SSL Supports TLSV1.2]) - ]) +fi + +dnl Now check if we are working with version 1.1.0 of openssl +if test "x$alpine_SSLTYPE" != "xnone" -a "x$alpine_SSLPROVIDER" != "xlibressl" ; then + AC_MSG_CHECKING([Openssl library version >= 1.1.0]) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include <stdio.h> +#include <stdlib.h> +#if HAVE_STDINT_H +#include <stdint.h> +#endif /* HAVE_STDINT_H */ +#include <openssl/ssl.h> +int main(void) { + + if (OPENSSL_VERSION_NUMBER >= 0x10100000L) + exit(0); + + exit(2); +} + ]])], + [ AC_MSG_RESULT(yes) + alpine_SSLVERSION="new" + CFLAGS="$CFLAGS -DOPENSSL_1_1_0 -DOPENSSL_API_COMPAT=0x10100000L" + ], + [ AC_MSG_RESULT(no) + alpine_SSLVERSION="old" ], + [ AC_MSG_WARN([cross compiling: not checking])]) fi dnl Crypto support is needed if test "x$alpine_SSLTYPE" != "xnone" ; then - AC_SEARCH_LIBS(SSLeay,crypto,, [ alpine_CRYPTO="none" ]) + if test "x$alpine_SSLVERSION" = "xold" -o "x$alpine_SSLPROVIDER" = "xlibressl" ; then + AC_SEARCH_LIBS(SSLeay,crypto,, [ alpine_CRYPTO="none" ]) + else + AC_SEARCH_LIBS(OpenSSL_version_num,crypto,, [ alpine_CRYPTO="none" ]) + fi if test "x$alpine_CRYPTO" = "xnone" ; then AC_MSG_ERROR(crypto library NOT found) exit 1 fi fi -dnl provide SSL support? if test "x$alpine_SSLTYPE" != "xnone" ; then - AC_SEARCH_LIBS(SSL_library_init,ssl,,[ alpine_SSLTYPE="none" ]) + if test "x$alpine_SSLVERSION" = "xold" -o "x$alpine_SSLPROVIDER" = "xlibressl" ; then + AC_SEARCH_LIBS(TLSv1_2_client_method,ssl, + [ alpine_c_client_cflags="$alpine_c_client_cflags -DTLSV1_2" + AC_DEFINE([SSL_SUPPORTS_TLSV1_2], [1], [SSL Supports TLSV1.2]) + ]) + else + AC_SEARCH_LIBS(TLS_client_method,ssl,, [ alpine_SSLTYPE="none"]) + AC_SEARCH_LIBS(DTLS_client_method,ssl,,[ alpine_SSLTYPE="none"]) + if test "x$alpine_SSLTYPE" != "xnone" ; then + AC_DEFINE([SSL_SUPPORTS_TLSV1_2], [1], [SSL Supports TLSV1.2]) + fi + fi +fi - if test "x$alpine_SSLTYPE" = "xnone" ; then - AC_MSG_ERROR(No library containing SSL_library_init found in your path) - exit 1 +dnl provide SSL support? +if test "x$alpine_SSLTYPE" != "xnone" ; then + if test "x$alpine_SSLVERSION" = "xold" -o "x$alpine_SSLPROVIDER" = "xlibressl" ; then + AC_SEARCH_LIBS(SSL_library_init,ssl,,[ alpine_SSLTYPE="none" ]) + if test "x$alpine_SSLTYPE" = "xnone" ; then + AC_MSG_ERROR(No library containing SSL_library_init found in your path) + exit 1 + fi + else + AC_SEARCH_LIBS(OPENSSL_init_ssl,ssl,, [ alpine_SSLTYPE="none" ]) + if test "x$alpine_SSLTYPE" = "xnone" ; then + AC_MSG_ERROR(No library containing OPENSSL_init_ssl found in your path) + exit 1 + fi fi - fi dnl provide LDAP support? diff --git a/imap/src/osdep/unix/ssl_unix.c b/imap/src/osdep/unix/ssl_unix.c index 16b4228c..9498eb0e 100644 --- a/imap/src/osdep/unix/ssl_unix.c +++ b/imap/src/osdep/unix/ssl_unix.c @@ -33,6 +33,10 @@ #include <bio.h> #include <crypto.h> #include <rand.h> +#ifdef OPENSSL_1_1_0 +#include <rsa.h> +#include <bn.h> +#endif /* OPENSSL_1_1_0 */ #undef STRING #undef crypt @@ -78,7 +82,14 @@ static long ssl_compare_hostnames (unsigned char *s,unsigned char *pat); static char *ssl_getline_work (SSLSTREAM *stream,unsigned long *size, long *contd); static long ssl_abort (SSLSTREAM *stream); -static RSA *ssl_genkey (SSL *con,int export,int keylength); + +#ifdef OPENSSL_1_1_0 +#define SSL_CTX_TYPE SSL_CTX +#else +#define SSL_CTX_TYPE SSL +#endif /* OPENSSL_1_1_0 */ + +static RSA *ssl_genkey (SSL_CTX_TYPE *con,int export,int keylength); /* Secure Sockets Layer network driver dispatch */ @@ -128,7 +139,11 @@ void ssl_onceonlyinit (void) /* apply runtime linkage */ mail_parameters (NIL,SET_SSLDRIVER,(void *) &ssldriver); mail_parameters (NIL,SET_SSLSTART,(void *) ssl_start); +#ifdef OPENSSL_1_1_0 + OPENSSL_init_ssl(0, NULL); +#else SSL_library_init (); /* add all algorithms */ +#endif /* OPENSSL_1_1_0 */ } } @@ -163,16 +178,26 @@ SSLSTREAM *ssl_aopen (NETMBX *mb,char *service,char *usrbuf) */ const SSL_METHOD *ssl_connect_mthd(int flag) { +#ifdef OPENSSL_1_1_0 if(flag & NET_TRYTLS1) - return TLSv1_client_method(); + return TLS_client_method(); +#else + if(flag & NET_TRYTLS1) + return TLSv1_client_method(); +#endif /* OPENSSL_1_1_0 */ #ifdef TLSV1_2 else if(flag & NET_TRYTLS1_1) return TLSv1_1_client_method(); else if(flag & NET_TRYTLS1_2) return TLSv1_2_client_method(); -#endif +#endif /* TLSV1_2 */ +#ifdef OPENSSL_1_1_0 + else if(flag & NET_TRYDTLS1) + return DTLS_client_method(); +#else else if(flag & NET_TRYDTLS1) return DTLSv1_client_method(); +#endif /* OPENSSL_1_1_0 */ else return SSLv23_client_method(); } @@ -242,7 +267,7 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags) BIO *bio; X509 *cert; unsigned long sl,tl; - char *s,*t,*err,tmp[MAILTMPLEN]; + char *s,*t,*err,tmp[MAILTMPLEN], buf[256]; sslcertificatequery_t scq = (sslcertificatequery_t) mail_parameters (NIL,GET_SSLCERTIFICATEQUERY,NIL); sslclientcert_t scc = @@ -300,9 +325,10 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags) (err = ssl_validate_cert (cert = SSL_get_peer_certificate (stream->con), host))) { /* application callback */ - if (scq) return (*scq) (err,host,cert ? cert->name : "???") ? NIL : ""; + X509_NAME_oneline (X509_get_subject_name(cert), buf, sizeof(buf)); + if (scq) return (*scq) (err,host,cert ? buf : "???") ? NIL : ""; /* error message to return via mm_log() */ - sprintf (tmp,"*%.128s: %.255s",err,cert ? cert->name : "???"); + sprintf (tmp,"*%.128s: %.255s",err,cert ? buf : "???"); return ssl_last_error = cpystr (tmp); } return NIL; @@ -346,20 +372,28 @@ static int ssl_open_verify (int ok,X509_STORE_CTX *ctx) static char *ssl_validate_cert (X509 *cert,char *host) { int i,n; - char *s,*t,*ret; + char *s=NULL,*t,*ret; void *ext; GENERAL_NAME *name; + X509_NAME *cname; + X509_NAME_ENTRY *e; + char buf[256]; /* make sure have a certificate */ if (!cert) ret = "No certificate from server"; /* and that it has a name */ - else if (!cert->name) ret = "No name in certificate"; + else if (!(cname = X509_get_subject_name(cert))) ret = "No name in certificate"; /* locate CN */ - else if ((s = strstr (cert->name,"/CN=")) != NULL) { - if ((t = strchr (s += 4,'/')) != NULL) *t = '\0'; + else{ + if((e = X509_NAME_get_entry(cname, X509_NAME_entry_count(cname)-1)) != NULL){ + X509_NAME_get_text_by_OBJ(cname, X509_NAME_ENTRY_get_object(e), buf, sizeof(buf)); + s = (char *) buf; + } + else s = NULL; + } + if (s != NULL) { /* host name matches pattern? */ ret = ssl_compare_hostnames (host,s) ? NIL : "Server name does not match certificate"; - if (t) *t = '/'; /* restore smashed delimiter */ /* if mismatch, see if in extensions */ if (ret && (ext = X509_get_ext_d2i (cert,NID_subject_alt_name,NIL,NIL)) && (n = sk_GENERAL_NAME_num (ext))) @@ -719,8 +753,13 @@ void ssl_server_init (char *server) SSLSTREAM *stream = (SSLSTREAM *) memset (fs_get (sizeof (SSLSTREAM)),0, sizeof (SSLSTREAM)); ssl_onceonlyinit (); /* make sure algorithms added */ +#ifdef OPENSSL_1_1_0 + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS|OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); +#else ERR_load_crypto_strings (); SSL_load_error_strings (); +#endif /* OPENSSL_1_1_0 */ /* build specific certificate/key file names */ sprintf (cert,"%s/%s-%s.pem",SSL_CERT_DIRECTORY,server,tcp_serveraddr ()); sprintf (key,"%s/%s-%s.pem",SSL_KEY_DIRECTORY,server,tcp_serveraddr ()); @@ -732,9 +771,15 @@ void ssl_server_init (char *server) if (stat (key,&sbuf)) strcpy (key,cert); } /* create context */ +#ifdef OPENSSL_1_1_0 + if (!(stream->context = SSL_CTX_new (start_tls ? + TLS_server_method () : + SSLv23_server_method ()))) +#else if (!(stream->context = SSL_CTX_new (start_tls ? TLSv1_server_method () : SSLv23_server_method ()))) +#endif /* OPENSSL_1_1_0 */ syslog (LOG_ALERT,"Unable to create SSL context, host=%.80s", tcp_clienthost ()); else { /* set context options */ @@ -754,8 +799,13 @@ void ssl_server_init (char *server) key,tcp_clienthost ()); else { /* generate key if needed */ +#ifdef OPENSSL_1_1_0 + if (0) + ssl_genkey(stream->context, 0, 0); +#else if (SSL_CTX_need_tmp_RSA (stream->context)) SSL_CTX_set_tmp_rsa_callback (stream->context,ssl_genkey); +#endif /* OPENSSL_1_1_0 */ /* create new SSL connection */ if (!(stream->con = SSL_new (stream->context))) syslog (LOG_ALERT,"Unable to create SSL connection, host=%.80s", @@ -798,19 +848,28 @@ void ssl_server_init (char *server) * Returns: generated key, always */ -static RSA *ssl_genkey (SSL *con,int export,int keylength) +static RSA *ssl_genkey (SSL_CTX_TYPE *con,int export,int keylength) { unsigned long i; static RSA *key = NIL; if (!key) { /* if don't have a key already */ /* generate key */ +#ifdef OPENSSL_1_1_0 + BIGNUM *e = BN_new(); + if (!RSA_generate_key_ex (key, export ? keylength : 1024, e,NIL)) { +#else if (!(key = RSA_generate_key (export ? keylength : 1024,RSA_F4,NIL,NIL))) { +#endif /* OPENSSL_1_1_0 */ syslog (LOG_ALERT,"Unable to generate temp key, host=%.80s", tcp_clienthost ()); while ((i = ERR_get_error ()) != 0L) syslog (LOG_ALERT,"SSL error status: %s",ERR_error_string (i,NIL)); exit (1); } +#ifdef OPENSSL_1_1_0 + BN_free(e); + e = NULL; +#endif /* OPENSSL_1_1_0 */ } return key; } diff --git a/pith/pine.hlp b/pith/pine.hlp index 5ee5e72c..6559f9d6 100644 --- a/pith/pine.hlp +++ b/pith/pine.hlp @@ -140,7 +140,7 @@ with help text for the config screen and the composer that didn't have any reasonable place to be called from. Dummy change to get revision in pine.hlp ============= h_revision ================= -Alpine Commit 166 2016-08-29 20:39:48 +Alpine Commit 167 2016-09-03 18:44:36 ============= h_news ================= <HTML> <HEAD> diff --git a/pith/smime.c b/pith/smime.c index 9629f743..389ce012 100644 --- a/pith/smime.c +++ b/pith/smime.c @@ -1238,8 +1238,12 @@ smime_init(void) s_cert_store = get_ca_store(); setup_certs_backup_by_type(CACert); +#ifdef OPENSSL_1_1_0 + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS|OPENSSL_INIT_ADD_ALL_DIGESTS|OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); +#else OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); +#endif /* OPENSSL_1_1_0 */ app_RAND_load_file(NULL); openssl_extra_randomness(); @@ -3142,8 +3146,8 @@ find_certificate_matching_recip_info(PKCS7_RECIP_INFO *ri) mine = x->cert; - if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,mine->cert_info->issuer) && - !ASN1_INTEGER_cmp(ri->issuer_and_serial->serial,mine->cert_info->serialNumber)){ + if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,X509_get_issuer_name(mine)) && + !ASN1_INTEGER_cmp(ri->issuer_and_serial->serial,X509_get_serialNumber(mine))){ break; } } diff --git a/pith/smkeys.c b/pith/smkeys.c index ce58ed41..8666d53b 100644 --- a/pith/smkeys.c +++ b/pith/smkeys.c @@ -62,11 +62,9 @@ smime_X509_to_cert_info(X509 *x, char *name) memset((void *)cert, 0, sizeof(CertList)); cert->x509_cert = x; cert->name = name ? cpystr(name) : NULL; - if(x && x->cert_info){ - cert->data.date_from = smime_get_date(x->cert_info->validity->notBefore); - cert->data.date_to = smime_get_date(x->cert_info->validity->notAfter); - cert->cn = smime_get_cn(x->cert_info->subject); - } + cert->data.date_from = smime_get_date(X509_get0_notBefore(x)); + cert->data.date_to = smime_get_date(X509_get0_notAfter(x)); + cert->cn = smime_get_cn(x); get_fingerprint(x, EVP_md5(), buf, sizeof(buf), NULL); cert->data.md5 = cpystr(buf); @@ -222,7 +220,7 @@ setup_certs_backup_by_type(WhichCerts ctype) case CACert: if((in = BIO_new_file(buf2, "r"))!=0){ x = PEM_read_bio_X509(in, NULL, NULL, NULL); - if(x && x->cert_info){ /* for now copy this information */ + if(x){ /* for now copy this information */ cert = smime_X509_to_cert_info(x, df->d_name); /* we will use the cert->data.md5 variable to find a backup certificate, not the name */ @@ -261,14 +259,20 @@ setup_certs_backup_by_type(WhichCerts ctype) } char * -smime_get_cn(X509_NAME *subject) +smime_get_cn(X509 *x) { - char buf[256]; X509_NAME_ENTRY *e; - e = X509_NAME_get_entry(subject, X509_NAME_entry_count(subject)-1); - if(e) - X509_NAME_get_text_by_OBJ(subject, e->object, buf, sizeof(buf)); - return cpystr(buf); + X509_NAME *subject; + char buf[256]; + char *rv = NULL; + + subject = X509_get_subject_name(x); + if((e = X509_NAME_get_entry(subject, X509_NAME_entry_count(subject)-1)) != NULL){ + X509_NAME_get_text_by_OBJ(subject, X509_NAME_ENTRY_get_object(e), buf, sizeof(buf)); + rv = cpystr(buf); + } + + return rv; } int @@ -395,7 +399,7 @@ emailstrclean(char *string) char * -smime_get_date(ASN1_GENERALIZEDTIME *tm) +smime_get_date(const ASN1_TIME *tm) { BIO *mb = BIO_new(BIO_s_mem()); char iobuf[4096]; @@ -476,13 +480,12 @@ add_certs_in_dir(X509_LOOKUP *lookup, char *path, char *ext, CertList **cdata) cert->name = cpystr(d->d_name); /* read buf into a bio and fill the CertData structure */ if((in = BIO_new_file(buf, "r"))!=0){ - x = PEM_read_bio_X509(in, NULL, NULL, NULL); - if(x && x->cert_info){ - cert->data.date_from = smime_get_date(x->cert_info->validity->notBefore); - cert->data.date_to = smime_get_date(x->cert_info->validity->notAfter); + if((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) != NULL){ + cert->data.date_from = smime_get_date(X509_get0_notBefore(x)); + cert->data.date_to = smime_get_date(X509_get0_notAfter(x)); get_fingerprint(x, EVP_md5(), buf, sizeof(buf), NULL); cert->data.md5 = cpystr(buf); - cert->cn = smime_get_cn(x->cert_info->subject); + cert->cn = smime_get_cn(x); X509_free(x); } BIO_free(in); diff --git a/pith/smkeys.h b/pith/smkeys.h index 8c23d905..0d3570bc 100644 --- a/pith/smkeys.h +++ b/pith/smkeys.h @@ -29,7 +29,16 @@ #include <openssl/pem.h> #include <openssl/err.h> #include <openssl/bio.h> +#include <openssl/safestack.h> +#ifndef OPENSSL_1_1_0 +#define X509_get0_notBefore(x) ((x) && (x)->cert_info \ + ? (x)->cert_info->validity->notBefore \ + : NULL) +#define X509_get0_notAfter(x) ((x) && (x)->cert_info \ + ? (x)->cert_info->validity->notAfter \ + : NULL) +#endif /* OPENSSL_1_1_0 */ #define EMAILADDRLEADER "emailAddress=" #define CACERTSTORELEADER "cacert=" @@ -64,10 +73,10 @@ void free_personal_certs(PERSONAL_CERT **pc); void get_fingerprint(X509 *cert, const EVP_MD *type, char *buf, size_t maxLen, char *s); int certlist_to_file(char *filename, CertList *certlist); int load_cert_for_key(char *pathdir, EVP_PKEY *pkey, char **certfile, X509 **pcert); -char *smime_get_date(ASN1_GENERALIZEDTIME *tm); +char *smime_get_date(const ASN1_TIME *tm); void resort_certificates(CertList **data, WhichCerts ctype); int setup_certs_backup_by_type(WhichCerts ctype); -char *smime_get_cn(X509_NAME *); +char *smime_get_cn(X509 *); CertList *smime_X509_to_cert_info(X509 *, char *); diff --git a/po/Makefile.in b/po/Makefile.in index e72ba769..eb7c1647 100644 --- a/po/Makefile.in +++ b/po/Makefile.in @@ -11,7 +11,7 @@ # Origin: gettext-0.16 PACKAGE = alpine -VERSION = 2.20.14 +VERSION = 2.20.15 PACKAGE_BUGREPORT = chappa@washington.edu SHELL = /bin/sh |