> Date: Fri, 28 Feb 2003 13:34:41 -0800
> From: Howard Chu <[EMAIL PROTECTED]>
> Subject: RE: EBCDIC
>
> I ported OpenLDAP, OpenSSL, Berkeley DB 4.1, and part of Cyrus SASL to
> OS/390. Aside from Cyrus, all of these packages were fully functional but
> OpenLDAP and OpenSSL operate with ASCII internally. [...]
>
> A lot of what I went thru is in the FAQ-o-Matic now
> http://www.openldap.org/faq/data/cache/719.html
Hello Howard, hello OpenSSL developers,
Excellent resource, thanks. For the OpenSSL patches, you fixed some
longstanding bugs (I had been aware of the TRUE/FALSE constant strings
-which were misconverted in the EBCDIC version-, and I find your
solution to it elegant).
At
http://www.openldap.org/faq/index.cgi?file=745
you print the set of patches to OpenSSL, and I verified them to work
on our BS2000 version of OpenSSL as well - the do indeed fix the problems
in the openssl application. One minor nit: in apps/ca.c, you subtract
the literal EBCDIC-'@' from an EBCDIC-char to construct the control-char;
this will not work, you must use 0x40 instead of '@' (fixed in
attached patch).
I vote for including the patch into mainstream OpenSSL. I repeat the
('@'-fixed) Howard Chu EBCDIC patch in this mail because the version
from http://www.openldap.org/faq/index.cgi?file=745 does not
apply cleanly (HTML-escapes present).
OpenSSL developers: this patch is against 0.9.6i, and is verified to
work for the IBM OS/390 and Fujitsu-Siemens BS2000(OSD/POSIX)
EBCDIC versions.
Thank you,
Martin Kraemer
--
<[EMAIL PROTECTED]> | Fujitsu Siemens
Fon: +49-89-636-46021, FAX: +49-89-636-47655 | 81730 Munich, Germany
--- ./crypto/asn1/a_print.c.orig Mon Mar 3 11:41:37 2003
+++ ./crypto/asn1/a_print.c Mon Mar 3 11:42:32 2003
@@ -116,27 +116,18 @@
while ((*s) && (len-- != 0))
{
c= *(s++);
-#ifndef CHARSET_EBCDIC
- if (!( ((c >= 'a') && (c <= 'z')) ||
- ((c >= 'A') && (c <= 'Z')) ||
- (c == ' ') ||
- ((c >= '0') && (c <= '9')) ||
- (c == ' ') || (c == '\'') ||
- (c == '(') || (c == ')') ||
- (c == '+') || (c == ',') ||
- (c == '-') || (c == '.') ||
- (c == '/') || (c == ':') ||
- (c == '=') || (c == '?')))
- ia5=1;
if (c&0x80)
+ {
t61=1;
-#else
- if (!isalnum(c) && (c != ' ') &&
- strchr("'()+,-./:=?", c) == NULL)
+ break;
+ }
+ if (!( ((c > 0x40) && (c < 0x5b)) || /* AZ */
+ ((c > 0x60) && (c < 0x7b)) || /* az */
+ ((c > 0x2a) && (c < 0x3b)) || /* +,-./09: */
+ (c == 0x20) || (c == 0x27) || /* SPC, ' */
+ (c == 0x28) || (c == 0x29) || /* () */
+ (c == 0x3d) || (c == 0x3f))) /* =? */
ia5=1;
- if (os_toascii[c] & 0x80)
- t61=1;
-#endif
}
if (t61) return(V_ASN1_T61STRING);
if (ia5) return(V_ASN1_IA5STRING);
--- ./apps/ca.c.orig Mon Mar 3 11:41:37 2003
+++ ./apps/ca.c Mon Mar 3 11:42:11 2003
@@ -1603,13 +1603,22 @@
p=(char *)str->data;
for (j=str->length; j>0; j--)
{
+#ifdef CHARSET_EBCDIC
+ if ((*p >= 0x20) && (*p <= 0x7e))
+ BIO_printf(bio_err,"%c", os_toebcdic[*p]);
+#else
if ((*p >= ' ') && (*p <= '~'))
BIO_printf(bio_err,"%c",*p);
+#endif
else if (*p & 0x80)
BIO_printf(bio_err,"\\0x%02X",*p);
else if ((unsigned char)*p == 0xf7)
BIO_printf(bio_err,"^?");
+#ifdef CHARSET_EBCDIC
+ else BIO_printf(bio_err,"^%c",os_toebcdic[*p+0x40]);
+#else
else BIO_printf(bio_err,"^%c",*p+'@');
+#endif
p++;
}
BIO_printf(bio_err,"'\n");
--- ./crypto/x509v3/v3_alt.c.orig Thu Mar 1 14:33:53 2001
+++ ./crypto/x509v3/v3_alt.c Mon Mar 3 11:44:22 2003
@@ -99,6 +99,15 @@
return ret;
}
+#ifdef CHARSET_EBCDIC
+static const char _unsup[] = {0x3c,0x75,0x6e,0x73,0x75,0x70,0x70,0x6f,
+ 0x72,0x74,0x65,0x64,0x3e,0 };
+static const char _inval[] = {0x3c,0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x3e,0};
+#else
+static const char _unsup[] = "<unsupported>";
+static const char _inval[] = "<invalid>";
+#endif
+
STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret)
{
@@ -107,15 +116,15 @@
switch (gen->type)
{
case GEN_OTHERNAME:
- X509V3_add_value("othername","<unsupported>", &ret);
+ X509V3_add_value("othername",_unsup, &ret);
break;
case GEN_X400:
- X509V3_add_value("X400Name","<unsupported>", &ret);
+ X509V3_add_value("X400Name",_unsup, &ret);
break;
case GEN_EDIPARTY:
- X509V3_add_value("EdiPartyName","<unsupported>", &ret);
+ X509V3_add_value("EdiPartyName",_unsup, &ret);
break;
case GEN_EMAIL:
@@ -132,6 +141,9 @@
case GEN_DIRNAME:
X509_NAME_oneline(gen->d.dirn, oline, 256);
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(oline, oline, strlen(oline));
+#endif
X509V3_add_value("DirName",oline, &ret);
break;
@@ -139,15 +151,21 @@
p = gen->d.ip->data;
/* BUG: doesn't support IPV6 */
if(gen->d.ip->length != 4) {
- X509V3_add_value("IP Address","<invalid>", &ret);
+ X509V3_add_value("IP Address",_inval, &ret);
break;
}
sprintf(oline, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(oline, oline, strlen(oline));
+#endif
X509V3_add_value("IP Address",oline, &ret);
break;
case GEN_RID:
i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(oline, oline, strlen(oline));
+#endif
X509V3_add_value("Registered ID",oline, &ret);
break;
}
@@ -383,6 +401,9 @@
}
if(is_string) {
+#ifdef CHARSET_EBCDIC
+ ebcdic2ascii(value, value, strlen(value));
+#endif
if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
!ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
strlen(value))) {
--- ./crypto/x509v3/v3_utl.c.orig Thu Feb 21 15:07:55 2002
+++ ./crypto/x509v3/v3_utl.c Mon Mar 3 11:41:38 2003
@@ -111,17 +111,25 @@
OPENSSL_free(conf);
}
+#ifdef CHARSET_EBCDIC
+static const char _true[] = {0x54, 0x52, 0x55, 0x45, 0x00 };
+static const char _false[] = {0x46, 0x41, 0x4c, 0x53, 0x45, 0x00};
+#else
+static const char _true[] = "TRUE";
+static const char _false[] = "FALSE";
+#endif
+
int X509V3_add_value_bool(const char *name, int asn1_bool,
STACK_OF(CONF_VALUE) **extlist)
{
- if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
- return X509V3_add_value(name, "FALSE", extlist);
+ if(asn1_bool) return X509V3_add_value(name, _true, extlist);
+ return X509V3_add_value(name, _false, extlist);
}
int X509V3_add_value_bool_nf(char *name, int asn1_bool,
STACK_OF(CONF_VALUE) **extlist)
{
- if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
+ if(asn1_bool) return X509V3_add_value(name, _true, extlist);
return 1;
}