[BTLS]: Use `int64_t` instead of `long` in the native API. (#3857)
authorMartin Baulig <martin.baulig@xamarin.com>
Mon, 7 Nov 2016 17:23:42 +0000 (18:23 +0100)
committerMartin Baulig <martin.baulig@xamarin.com>
Mon, 7 Nov 2016 17:25:17 +0000 (18:25 +0100)
* [BTLS]: Use `int64_t` instead of `long` in the native API.

* Copy time64.c from Android's source code to get a 64-bit timegm64().

* Rename into btls_timegm64() and remove everything we don't need.

(cherry picked from commit 2365067bdae39f75979df30b65ae08f095cbd176)

18 files changed:
mono/btls/CMakeLists.txt
mono/btls/btls-android-utils.c [deleted file]
mono/btls/btls-bio.c
mono/btls/btls-bio.h
mono/btls/btls-time64.c [new file with mode: 0644]
mono/btls/btls-util.c
mono/btls/btls-util.h
mono/btls/btls-x509-crl.c
mono/btls/btls-x509-crl.h
mono/btls/btls-x509-lookup-mono.c
mono/btls/btls-x509-name.c
mono/btls/btls-x509-name.h
mono/btls/btls-x509-revoked.c
mono/btls/btls-x509-revoked.h
mono/btls/btls-x509-verify-param.c
mono/btls/btls-x509-verify-param.h
mono/btls/btls-x509.c
mono/btls/btls-x509.h

index ddd976ccd2089a79a4daff0e16ee01c7e1536714..7c3fb3d2c72fe03d751753e5f811c2793ae03e30 100644 (file)
@@ -51,6 +51,7 @@ set (
        btls-ssl-ctx.h
        btls-ssl.c
        btls-ssl.h
+       btls-time64.c
        btls-util.c
        btls-util.h
        btls-x509-chain.c
@@ -74,8 +75,6 @@ set (
        btls-x509.c
        btls-x509.h
 
-       btls-android-utils.c
-
        ${BORINGSSL_OBJECTS}
 )
 
diff --git a/mono/btls/btls-android-utils.c b/mono/btls/btls-android-utils.c
deleted file mode 100644 (file)
index df30f85..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copied from Chromium: https://src.chromium.org/svn/trunk/src/base/os_compat_android.cc
-
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#if defined(__ANDROID__)
-
-#include <asm/unistd.h>
-#include <errno.h>
-#include <math.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-
-#if !defined(__LP64__)
-#include <time64.h>
-#endif
-
-#if !defined(__LP64__)
-// 32-bit Android has only timegm64() and not timegm().
-// We replicate the behaviour of timegm() when the result overflows time_t.
-time_t timegm(struct tm* const t) {
-  // time_t is signed on Android.
-  static const time_t kTimeMax = ~(1L << (sizeof(time_t) * CHAR_BIT - 1));
-  static const time_t kTimeMin = (1L << (sizeof(time_t) * CHAR_BIT - 1));
-  time64_t result = timegm64(t);
-  if (result < kTimeMin || result > kTimeMax)
-    return -1;
-  return result;
-}
-#endif
-
-#endif
index ea8fda67dc35096689e0e580561e7e4b68b38577..a35582a3b57f32e50bc759d8eaaaef7117fe6733 100644 (file)
@@ -64,8 +64,8 @@ mono_write (BIO *bio, const char *in, int inl)
        return mono->write_func (mono->instance, in, inl);
 }
 
-static long
-mono_ctrl (BIO *bio, int cmd, long num, void *ptr)
+static int64_t
+mono_ctrl (BIO *bio, int cmd, int64_t num, void *ptr)
 {
        MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr;
 
index d4429f6d6289d49bb7454e3bb9ae3b82237051ab..0795ef0f2ba1918be0ddf2ae9e8d40c11493fe07 100644 (file)
@@ -18,7 +18,7 @@ typedef enum {
 
 typedef int (* MonoBtlsReadFunc) (const void *instance, const void *buf, int size, int *wantMore);
 typedef int (* MonoBtlsWriteFunc) (const void *instance, const void *buf, int size);
-typedef long (* MonoBtlsControlFunc) (const void *instance, MonoBtlsControlCommand command, long arg);
+typedef int64_t (* MonoBtlsControlFunc) (const void *instance, MonoBtlsControlCommand command, int64_t arg);
 
 BIO *
 mono_btls_bio_mono_new (void);
diff --git a/mono/btls/btls-time64.c b/mono/btls/btls-time64.c
new file mode 100644 (file)
index 0000000..f01e8c0
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+
+Copyright (c) 2007-2008  Michael G Schwern
+
+This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
+
+The MIT License:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+/* See http://code.google.com/p/y2038 for this code's origin */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+/* Spec says except for stftime() and the _r() functions, these
+   all return static memory.  Stabbings! */
+static struct tm   Static_Return_Date;
+static char        Static_Return_String[35];
+
+static const int days_in_month[2][12] = {
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+};
+
+static const int julian_days_by_month[2][12] = {
+    {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
+    {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335},
+};
+
+static char const wday_name[7][3] = {
+    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
+
+static char const mon_name[12][3] = {
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static const int length_of_year[2] = { 365, 366 };
+
+/* Some numbers relating to the gregorian cycle */
+static const int64_t     years_in_gregorian_cycle   = 400;
+#define               days_in_gregorian_cycle      ((365 * 400) + 100 - 4 + 1)
+static const int64_t seconds_in_gregorian_cycle = days_in_gregorian_cycle * 60LL * 60LL * 24LL;
+
+/* Year range we can trust the time funcitons with */
+#define MAX_SAFE_YEAR 2037
+#define MIN_SAFE_YEAR 1971
+
+/* 28 year Julian calendar cycle */
+#define SOLAR_CYCLE_LENGTH 28
+
+/* Year cycle from MAX_SAFE_YEAR down. */
+static const int safe_years_high[SOLAR_CYCLE_LENGTH] = {
+    2016, 2017, 2018, 2019,
+    2020, 2021, 2022, 2023,
+    2024, 2025, 2026, 2027,
+    2028, 2029, 2030, 2031,
+    2032, 2033, 2034, 2035,
+    2036, 2037, 2010, 2011,
+    2012, 2013, 2014, 2015
+};
+
+/* Year cycle from MIN_SAFE_YEAR up */
+static const int safe_years_low[SOLAR_CYCLE_LENGTH] = {
+    1996, 1997, 1998, 1971,
+    1972, 1973, 1974, 1975,
+    1976, 1977, 1978, 1979,
+    1980, 1981, 1982, 1983,
+    1984, 1985, 1986, 1987,
+    1988, 1989, 1990, 1991,
+    1992, 1993, 1994, 1995,
+};
+
+/* Let's assume people are going to be looking for dates in the future.
+   Let's provide some cheats so you can skip ahead.
+   This has a 4x speed boost when near 2008.
+*/
+/* Number of days since epoch on Jan 1st, 2008 GMT */
+#define CHEAT_DAYS  (1199145600 / 24 / 60 / 60)
+#define CHEAT_YEARS 108
+
+#define IS_LEAP(n)      ((!(((n) + 1900) % 400) || (!(((n) + 1900) % 4) && (((n) + 1900) % 100))) != 0)
+#define WRAP(a,b,m)     ((a) = ((a) <  0  ) ? ((b)--, (a) + (m)) : (a))
+
+/* timegm() is not in the C or POSIX spec, but it is such a useful
+   extension I would be remiss in leaving it out.  Also I need it
+   for localtime64()
+*/
+int64_t btls_timegm64(const struct tm *date) {
+    int64_t days    = 0;
+    int64_t seconds = 0;
+    int64_t     year;
+    int64_t     orig_year = (int64_t)date->tm_year;
+    int      cycles  = 0;
+
+    if( orig_year > 100 ) {
+        cycles = (orig_year - 100) / 400;
+        orig_year -= cycles * 400;
+        days      += (int64_t)cycles * days_in_gregorian_cycle;
+    }
+    else if( orig_year < -300 ) {
+        cycles = (orig_year - 100) / 400;
+        orig_year -= cycles * 400;
+        days      += (int64_t)cycles * days_in_gregorian_cycle;
+    }
+
+    if( orig_year > 70 ) {
+        year = 70;
+        while( year < orig_year ) {
+            days += length_of_year[IS_LEAP(year)];
+            year++;
+        }
+    }
+    else if ( orig_year < 70 ) {
+        year = 69;
+        do {
+            days -= length_of_year[IS_LEAP(year)];
+            year--;
+        } while( year >= orig_year );
+    }
+
+
+    days += julian_days_by_month[IS_LEAP(orig_year)][date->tm_mon];
+    days += date->tm_mday - 1;
+
+    seconds = days * 60 * 60 * 24;
+
+    seconds += date->tm_hour * 60 * 60;
+    seconds += date->tm_min * 60;
+    seconds += date->tm_sec;
+
+    return(seconds);
+}
index 824b101f34c50ed68b88fd0e804a050ed7add745..7c7f4ca5b41a511496b431425788a3531f425749 100644 (file)
@@ -8,32 +8,33 @@
 
 #include <btls-util.h>
 #include <assert.h>
-#include <time.h>
-
-#if defined(__ANDROID__) && !defined(__LP64__)
-#include <time64.h>
-extern time_t timegm (struct tm* const t);
-#endif
+// #include <time.h>
 
 extern int asn1_generalizedtime_to_tm (struct tm *tm, const ASN1_GENERALIZEDTIME *d);
 
+extern int64_t btls_timegm64 (const struct tm *date);
+
+
 MONO_API void
 mono_btls_free (void *data)
 {
        OPENSSL_free (data);
 }
 
-long
+int64_t
 mono_btls_util_asn1_time_to_ticks (ASN1_TIME *time)
 {
        ASN1_GENERALIZEDTIME *gtime;
        struct tm tm;
-       time_t epoch;
+       int64_t epoch;
+       int ret;
+       
+       memset (&tm, 0, sizeof (tm));
 
        gtime = ASN1_TIME_to_generalizedtime (time, NULL);
-       asn1_generalizedtime_to_tm (&tm, gtime);
+       ret = asn1_generalizedtime_to_tm (&tm, gtime);
        ASN1_GENERALIZEDTIME_free (gtime);
-       epoch = timegm(&tm);
+       epoch = btls_timegm64 (&tm);
 
        return epoch;
 }
index 525e619975075b353cf87ca15b5669e87cb2f06a..a1b165235bd50eca05375db37681b9558f3dc89a 100644 (file)
@@ -33,7 +33,7 @@
 void
 mono_btls_free (void *data);
 
-long
+int64_t
 mono_btls_util_asn1_time_to_ticks (ASN1_TIME *time);
 
 int
index b4e861234cac0ed758b794fd3089de0f08689056..d496c072f1270b477ef6590b60e263746c6ab5b5 100644 (file)
@@ -124,19 +124,19 @@ mono_btls_x509_crl_get_revoked (MonoBtlsX509Crl *crl, int index)
        return mono_btls_x509_revoked_new (crl, revoked);
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_crl_get_last_update (MonoBtlsX509Crl *crl)
 {
        return mono_btls_util_asn1_time_to_ticks (X509_CRL_get_lastUpdate (crl->crl));
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_crl_get_next_update (MonoBtlsX509Crl *crl)
 {
        return mono_btls_util_asn1_time_to_ticks (X509_CRL_get_nextUpdate (crl->crl));
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_crl_get_version (MonoBtlsX509Crl *crl)
 {
        return X509_CRL_get_version (crl->crl);
index 0813fe5436adc0e8b59af330aed0fc1b69815fe0..625037d99a2ab747cb57725807246be32192f40d 100644 (file)
@@ -34,13 +34,13 @@ mono_btls_x509_crl_get_revoked_count (MonoBtlsX509Crl *crl);
 MonoBtlsX509Revoked *
 mono_btls_x509_crl_get_revoked (MonoBtlsX509Crl *crl, int index);
 
-long
+int64_t
 mono_btls_x509_crl_get_last_update (MonoBtlsX509Crl *crl);
 
-long
+int64_t
 mono_btls_x509_crl_get_next_update (MonoBtlsX509Crl *crl);
 
-long
+int64_t
 mono_btls_x509_crl_get_version (MonoBtlsX509Crl *crl);
 
 MonoBtlsX509Name *
index 1d8f7d3ee51f081d4674000fc9160995939a80c3..6d9d69a16f0670c2006e37e5d641a08b4efcdbfa 100644 (file)
@@ -103,7 +103,7 @@ mono_btls_x509_lookup_mono_free (MonoBtlsX509LookupMono *mono)
 }
 
 static int
-mono_lookup_ctrl (X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret)
+mono_lookup_ctrl (X509_LOOKUP *ctx, int cmd, const char *argp, int64_t argl, char **ret)
 {
        MonoLookup *lookup = (MonoLookup*)ctx->method_data;
        MonoBtlsX509LookupMono *mono = (MonoBtlsX509LookupMono*)argp;
index 782743f875259bfe50b4c4d3a8a6e91ea36d2f19..7f9875880026f712fcf673f1e58c74408472a8de 100644 (file)
@@ -153,13 +153,13 @@ mono_btls_x509_name_print_string (MonoBtlsX509Name *name, char *buffer, int size
        return X509_NAME_oneline (name->name, buffer, size) != NULL;
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_name_hash (MonoBtlsX509Name *name)
 {
        return X509_NAME_hash (name->name);
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_name_hash_old (MonoBtlsX509Name *name)
 {
        return X509_NAME_hash_old (name->name);
index 604de2bb5e6627a682debcd033b3c4bb23420cd3..9d43bc6499158cda4ba795b5691aa2be2ed96320 100644 (file)
@@ -56,10 +56,10 @@ mono_btls_x509_name_print_string (MonoBtlsX509Name *name, char *buffer, int size
 int
 mono_btls_x509_name_get_raw_data (MonoBtlsX509Name *name, void **buffer, int use_canon_enc);
 
-long
+int64_t
 mono_btls_x509_name_hash (MonoBtlsX509Name *name);
 
-long
+int64_t
 mono_btls_x509_name_hash_old (MonoBtlsX509Name *name);
 
 int
index d0540e6ca10f872f868719aee9007e493739a325..bf9af79de46920f7964e2b2032bb30f39177a2b7 100644 (file)
@@ -46,7 +46,7 @@ mono_btls_x509_revoked_get_serial_number (MonoBtlsX509Revoked *revoked, char *bu
        return serial->length;
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_revoked_get_revocation_date (MonoBtlsX509Revoked *revoked)
 {
        ASN1_TIME *date;
index e1229c6a47f211f17e0eb9744438d120c4be703b..592fc9316a1bc534a28a815c956f5682e5af1a3e 100644 (file)
@@ -22,7 +22,7 @@ mono_btls_x509_revoked_free (MonoBtlsX509Revoked *revoked);
 int
 mono_btls_x509_revoked_get_serial_number (MonoBtlsX509Revoked *revoked, char *buffer, int size);
 
-long
+int64_t
 mono_btls_x509_revoked_get_revocation_date (MonoBtlsX509Revoked *revoked);
 
 int
index 5ac8bdbb099c574de77c2cef4c7831829a107271..24be3da8ca11acb6805686730210ff3b36cde3f8 100644 (file)
@@ -126,14 +126,14 @@ mono_btls_x509_verify_param_add_host (MonoBtlsX509VerifyParam *param, const char
        return X509_VERIFY_PARAM_set1_host (param->param, host, namelen);
 }
 
-MONO_API unsigned long
+MONO_API uint64_t
 mono_btls_x509_verify_param_get_flags (MonoBtlsX509VerifyParam *param)
 {
        return X509_VERIFY_PARAM_get_flags (param->param);
 }
 
 MONO_API int
-mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, unsigned long flags)
+mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, uint64_t flags)
 {
        if (!param->owns)
                return -1;
@@ -144,7 +144,7 @@ MONO_API MonoBtlsX509VerifyFlags
 mono_btls_x509_verify_param_get_mono_flags (MonoBtlsX509VerifyParam *param)
 {
        MonoBtlsX509VerifyFlags current;
-       unsigned long flags;
+       uint64_t flags;
 
        if (!param->owns)
                return -1;
@@ -165,7 +165,7 @@ mono_btls_x509_verify_param_get_mono_flags (MonoBtlsX509VerifyParam *param)
 MONO_API int
 mono_btls_x509_verify_param_set_mono_flags (MonoBtlsX509VerifyParam *param, MonoBtlsX509VerifyFlags flags)
 {
-       unsigned long current;
+       uint64_t current;
 
        if (!param->owns)
                return -1;
@@ -205,7 +205,7 @@ mono_btls_x509_verify_param_set_depth (MonoBtlsX509VerifyParam *param, int depth
 }
 
 MONO_API int
-mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, long time)
+mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, int64_t time)
 {
        if (!param->owns)
                return -1;
index 6f4f1b51a8e71c3d34440cbd44b858aedcd30db5..e85d547fb3e68ec37268024e08734ebb7a8de216 100644 (file)
@@ -50,11 +50,11 @@ mono_btls_x509_verify_param_set_host (MonoBtlsX509VerifyParam *param, const char
 int
 mono_btls_x509_verify_param_add_host (MonoBtlsX509VerifyParam *param, const char *host, int namelen);
 
-unsigned long
+uint64_t
 mono_btls_x509_verify_param_get_flags (MonoBtlsX509VerifyParam *param);
 
 int
-mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, unsigned long flags);
+mono_btls_x509_verify_param_set_flags (MonoBtlsX509VerifyParam *param, uint64_t flags);
 
 MonoBtlsX509VerifyFlags
 mono_btls_x509_verify_param_get_mono_flags (MonoBtlsX509VerifyParam *param);
@@ -72,7 +72,7 @@ int
 mono_btls_x509_verify_param_set_depth (MonoBtlsX509VerifyParam *param, int depth);
 
 int
-mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, long time);
+mono_btls_x509_verify_param_set_time (MonoBtlsX509VerifyParam *param, int64_t time);
 
 char *
 mono_btls_x509_verify_param_get_peername (MonoBtlsX509VerifyParam *param);
index ae75f3ce9128b95cb9d53d34b7292a84b06b1e15..473d94fbaf3e341d0d7851860952bf6de7216bc8 100644 (file)
@@ -101,13 +101,13 @@ mono_btls_x509_get_hash (X509 *x509, const void **data)
        return SHA_DIGEST_LENGTH;
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_get_not_before (X509 *x509)
 {
        return mono_btls_util_asn1_time_to_ticks (X509_get_notBefore (x509));
 }
 
-MONO_API long
+MONO_API int64_t
 mono_btls_x509_get_not_after (X509 *x509)
 {
        return mono_btls_util_asn1_time_to_ticks (X509_get_notAfter (x509));
index a9a9200127d47ee4b011e85908e7f8fd60132036..d9137431333d46cca5ffbf7f9f25ce25a456300c 100644 (file)
@@ -79,10 +79,10 @@ mono_btls_x509_cmp (const X509 *a, const X509 *b);
 int
 mono_btls_x509_get_hash (X509 *x509, const void **data);
 
-long
+int64_t
 mono_btls_x509_get_not_before (X509 *x509);
 
-long
+int64_t
 mono_btls_x509_get_not_after (X509 *x509);
 
 int