diff options
author | opensslonzos-github <opensslonzos-github@yahoo.com> | 2019-08-08 14:11:38 -0400 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2019-08-14 10:41:41 +0100 |
commit | 48102247ff513d4c57b40b19c1d432f37b9e4b02 (patch) | |
tree | 26afaf1a8a6fb2ec673f2cb402d71517bb32da84 /crypto | |
parent | 86333b6e0c5c488130ab237e95b8520891b81bf6 (diff) |
Add missing EBCDIC strings
Fix a few places where calling ossl_isdigit does the wrong thing on
EBCDIC based systems.
Replaced with ascii_isdigit.
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9556)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/asn1/a_time.c | 43 | ||||
-rw-r--r-- | crypto/ctype.c | 6 | ||||
-rw-r--r-- | crypto/include/internal/ctype.h | 2 | ||||
-rw-r--r-- | crypto/rand/rand_lcl.h | 6 | ||||
-rw-r--r-- | crypto/x509/x509_vfy.c | 10 |
5 files changed, 45 insertions, 22 deletions
diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c index 491909b08e..16f0cc3fe3 100644 --- a/crypto/asn1/a_time.c +++ b/crypto/asn1/a_time.c @@ -79,7 +79,11 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) char *a; int n, i, i2, l, o, min_l = 11, strict = 0, end = 6, btz = 5, md; struct tm tmp; - +#if defined(CHARSET_EBCDIC) + const char upper_z = 0x5A, num_zero = 0x30, period = 0x2E, minus = 0x2D, plus = 0x2B; +#else + const char upper_z = 'Z', num_zero = '0', period = '.', minus = '-', plus = '+'; +#endif /* * ASN1_STRING_FLAG_X509_TIME is used to enforce RFC 5280 * time string format, in which: @@ -120,20 +124,20 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) if (l < min_l) goto err; for (i = 0; i < end; i++) { - if (!strict && (i == btz) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { + if (!strict && (i == btz) && ((a[o] == upper_z) || (a[o] == plus) || (a[o] == minus))) { i++; break; } - if (!ossl_isdigit(a[o])) + if (!ascii_isdigit(a[o])) goto err; - n = a[o] - '0'; + n = a[o] - num_zero; /* incomplete 2-digital number */ if (++o == l) goto err; - if (!ossl_isdigit(a[o])) + if (!ascii_isdigit(a[o])) goto err; - n = (n * 10) + a[o] - '0'; + n = (n * 10) + a[o] - num_zero; /* no more bytes to read, but we haven't seen time-zone yet */ if (++o == l) goto err; @@ -185,14 +189,14 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) * Optional fractional seconds: decimal point followed by one or more * digits. */ - if (d->type == V_ASN1_GENERALIZEDTIME && a[o] == '.') { + if (d->type == V_ASN1_GENERALIZEDTIME && a[o] == period) { if (strict) /* RFC 5280 forbids fractional seconds */ goto err; if (++o == l) goto err; i = o; - while ((o < l) && ossl_isdigit(a[o])) + while ((o < l) && ascii_isdigit(a[o])) o++; /* Must have at least one digit after decimal point */ if (i == o) @@ -207,10 +211,10 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) * 'o' can point to '\0' is either the subsequent if or the first * else if is true. */ - if (a[o] == 'Z') { + if (a[o] == upper_z) { o++; - } else if (!strict && ((a[o] == '+') || (a[o] == '-'))) { - int offsign = a[o] == '-' ? 1 : -1; + } else if (!strict && ((a[o] == plus) || (a[o] == minus))) { + int offsign = a[o] == minus ? 1 : -1; int offset = 0; o++; @@ -223,13 +227,13 @@ int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *d) if (o + 4 != l) goto err; for (i = end; i < end + 2; i++) { - if (!ossl_isdigit(a[o])) + if (!ascii_isdigit(a[o])) goto err; - n = a[o] - '0'; + n = a[o] - num_zero; o++; - if (!ossl_isdigit(a[o])) + if (!ascii_isdigit(a[o])) goto err; - n = (n * 10) + a[o] - '0'; + n = (n * 10) + a[o] - num_zero; i2 = (d->type == V_ASN1_UTCTIME) ? i + 1 : i; if ((n < min[i2]) || (n > max[i2])) goto err; @@ -300,7 +304,7 @@ ASN1_TIME *asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type) ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec); -#ifdef CHARSET_EBCDIC_not +#ifdef CHARSET_EBCDIC ebcdic2ascii(tmps->data, tmps->data, tmps->length); #endif return tmps; @@ -467,6 +471,7 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) char *v; int gmt = 0, l; struct tm stm; + const char upper_z = 0x5A, period = 0x2E; if (!asn1_time_to_tm(&stm, tm)) { /* asn1_time_to_tm will check the time type */ @@ -475,7 +480,7 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) l = tm->length; v = (char *)tm->data; - if (v[l - 1] == 'Z') + if (v[l - 1] == upper_z) gmt = 1; if (tm->type == V_ASN1_GENERALIZEDTIME) { @@ -486,10 +491,10 @@ int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) * Try to parse fractional seconds. '14' is the place of * 'fraction point' in a GeneralizedTime string. */ - if (tm->length > 15 && v[14] == '.') { + if (tm->length > 15 && v[14] == period) { f = &v[14]; f_len = 1; - while (14 + f_len < l && ossl_isdigit(f[f_len])) + while (14 + f_len < l && ascii_isdigit(f[f_len])) ++f_len; } diff --git a/crypto/ctype.c b/crypto/ctype.c index e7aa606827..e7bc25b976 100644 --- a/crypto/ctype.c +++ b/crypto/ctype.c @@ -272,3 +272,9 @@ int ossl_toupper(int c) { return ossl_islower(c) ? c ^ case_change : c; } + +int ascii_isdigit(const char inchar) { + if (inchar > 0x2F && inchar < 0x3A) + return 1; + return 0; +} diff --git a/crypto/include/internal/ctype.h b/crypto/include/internal/ctype.h index adcbc8b3d5..d0660cf9c4 100644 --- a/crypto/include/internal/ctype.h +++ b/crypto/include/internal/ctype.h @@ -57,6 +57,8 @@ int ossl_ctype_check(int c, unsigned int mask); int ossl_tolower(int c); int ossl_toupper(int c); +int ascii_isdigit(const char inchar); + # define ossl_isalnum(c) (ossl_ctype_check((c), CTYPE_MASK_alnum)) # define ossl_isalpha(c) (ossl_ctype_check((c), CTYPE_MASK_alpha)) # ifdef CHARSET_EBCDIC diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h index e425d41090..c954cf5f39 100644 --- a/crypto/rand/rand_lcl.h +++ b/crypto/rand/rand_lcl.h @@ -54,7 +54,13 @@ # define DRBG_MAX_LENGTH INT32_MAX /* The default nonce */ +#ifdef CHARSET_EBCDIC +# define DRBG_DEFAULT_PERS_STRING { 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, \ + 0x4c, 0x20, 0x4e, 0x49, 0x53, 0x54, 0x20, 0x53, 0x50, 0x20, 0x38, 0x30, \ + 0x30, 0x2d, 0x39, 0x30, 0x41, 0x20, 0x44, 0x52, 0x42, 0x47, 0x00}; +#else # define DRBG_DEFAULT_PERS_STRING "OpenSSL NIST SP 800-90A DRBG" +#endif /* * Maximum allocation size for RANDOM_POOL buffers diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 0282c7aa9e..f337cd14cb 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -1788,7 +1788,11 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1; ASN1_TIME *asn1_cmp_time = NULL; int i, day, sec, ret = 0; - +#ifdef CHARSET_EBCDIC + const char upper_z = 0x5A; +#else + const char upper_z = 'Z'; +#endif /* * Note that ASN.1 allows much more slack in the time format than RFC5280. * In RFC5280, the representation is fixed: @@ -1819,10 +1823,10 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) * Digit and date ranges will be verified in the conversion methods. */ for (i = 0; i < ctm->length - 1; i++) { - if (!ossl_isdigit(ctm->data[i])) + if (!ascii_isdigit(ctm->data[i])) return 0; } - if (ctm->data[ctm->length - 1] != 'Z') + if (ctm->data[ctm->length - 1] != upper_z) return 0; /* |