Support the EBCDIC character set and BS2000/OSD-POSIX (work in progress).
authorUlf Möller <ulf@openssl.org>
Fri, 4 Jun 1999 21:35:58 +0000 (21:35 +0000)
committerUlf Möller <ulf@openssl.org>
Fri, 4 Jun 1999 21:35:58 +0000 (21:35 +0000)
Submitted by: Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>

34 files changed:
CHANGES
Configure
apps/req.c
apps/s_client.c
apps/s_server.c
crypto/Makefile.ssl
crypto/asn1/a_gentm.c
crypto/asn1/a_print.c
crypto/asn1/a_time.c
crypto/asn1/a_utctm.c
crypto/asn1/f_int.c
crypto/asn1/f_string.c
crypto/asn1/t_x509.c
crypto/bf/bftest.c
crypto/bio/b_dump.c
crypto/conf/conf_lcl.h
crypto/crypto.h
crypto/des/fcrypt.c
crypto/err/err.c
crypto/evp/encode.c
crypto/hmac/hmactest.c
crypto/md2/md2_one.c
crypto/md2/md2test.c
crypto/md5/md5.c
crypto/md5/md5_one.c
crypto/mdc2/mdc2test.c
crypto/objects/obj_dat.c
crypto/pem/pem_lib.c
crypto/ripemd/rmd160.c
crypto/ripemd/rmdtest.c
crypto/sha/sha1.c
crypto/sha/sha1test.c
crypto/sha/shatest.c
crypto/x509/x509_obj.c

diff --git a/CHANGES b/CHANGES
index 83e4ee4..33e474a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,16 @@
 
  Changes between 0.9.3a and 0.9.4
 
+  *) config now generates no-xxx options for missing ciphers.
+     [Ulf Möller]
+
+  *) Support the EBCDIC character set (work in progress).
+     File ebcdic.c not yet included because it has a different license.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+  *) Support BS2000/OSD-POSIX.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
   *) Make callbacks for key generation use void * instead of char *.
      [Ben Laurie]
 
index 1359050..19bef03 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -231,6 +231,9 @@ my %table=(
 "SINIX","cc:-O -DSNI:(unknown):-lsocket -lnsl -lc -L/usr/ucblib -lucb:RC4_INDEX RC4_CHAR:::",
 "SINIX-N","/usr/ucb/cc:-O2 -misaligned:(unknown):-lucb:RC4_INDEX RC4_CHAR:::",
 
+# SIEMENS BS2000/OSD: an EBCDIC-based mainframe
+"BS2000-OSD","c89:-XLLML -XLLMK -XL -DB_ENDIAN -DTERMIOS -DCHARSET_EBCDIC:-lsocket -lnsl:THIRTY_TWO_BIT DES_PTR DES_UNROLL MD2_CHAR RC4_INDEX RC4_CHAR BF_PTR:::",
+
 # Windows NT, Microsoft Visual C++ 4.0
 
 "VC-NT","cl::(unknown)::BN_LLONG RC4_INDEX ${x86_gcc_opts}:::",
index dff16a6..cb30888 100644 (file)
@@ -1013,6 +1013,9 @@ static int add_DN_object(X509_NAME *n, char *text, char *def, char *value,
        j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
        if (req_fix_data(nid,&j,i,min,max) == 0)
                goto err;
+#ifdef CHARSET_EBCDIC
+       ebcdic2ascii(buf, buf, i);
+#endif
        if ((ne=X509_NAME_ENTRY_create_by_NID(NULL,nid,j,(unsigned char *)buf,
                strlen(buf)))
                == NULL) goto err;
index 81617af..84133b8 100644 (file)
@@ -555,6 +555,9 @@ re_start:
 #ifndef WINDOWS
                else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
                        {
+#ifdef CHARSET_EBCDIC
+                       ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
+#endif
                        i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);
 
                        if (i <= 0)
@@ -648,6 +651,9 @@ printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240
                                {
                                cbuf_len=i;
                                cbuf_off=0;
+#ifdef CHARSET_EBCDIC
+                               ebcdic2ascii(cbuf, cbuf, i);
+#endif
                                }
 
                        write_ssl=1;
index 0a25d8c..e1588c5 100644 (file)
@@ -235,6 +235,156 @@ static int local_argc=0;
 static char **local_argv;
 static int hack=0;
 
+#ifdef CHARSET_EBCDIC
+static int ebcdic_new(BIO *bi);
+static int ebcdic_free(BIO *a);
+static int ebcdic_read(BIO *b, char *out, int outl);
+static int ebcdic_write(BIO *b, char *in, int inl);
+static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr);
+static int ebcdic_gets(BIO *bp, char *buf, int size);
+static int ebcdic_puts(BIO *bp, char *str);
+
+#define BIO_TYPE_EBCDIC_FILTER (18|0x0200)
+static BIO_METHOD methods_ebcdic=
+       {
+       BIO_TYPE_EBCDIC_FILTER,
+       "EBCDIC/ASCII filter",
+       ebcdic_write,
+       ebcdic_read,
+       ebcdic_puts,
+       ebcdic_gets,
+       ebcdic_ctrl,
+       ebcdic_new,
+       ebcdic_free,
+       };
+
+typedef struct
+{
+       size_t  alloced;
+       char    buff[1];
+} EBCDIC_OUTBUFF;
+
+BIO_METHOD *BIO_f_ebcdic_filter()
+{
+       return(&methods_ebcdic);
+}
+
+static int ebcdic_new(BIO *bi)
+{
+       EBCDIC_OUTBUFF *wbuf;
+
+       wbuf = (EBCDIC_OUTBUFF *)Malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
+       wbuf->alloced = 1024;
+       wbuf->buff[0] = '\0';
+
+       bi->ptr=(char *)wbuf;
+       bi->init=1;
+       bi->flags=0;
+       return(1);
+}
+
+static int ebcdic_free(BIO *a)
+{
+       if (a == NULL) return(0);
+       if (a->ptr != NULL)
+               Free(a->ptr);
+       a->ptr=NULL;
+       a->init=0;
+       a->flags=0;
+       return(1);
+}
+       
+static int ebcdic_read(BIO *b, char *out, int outl)
+{
+       int ret=0;
+
+       if (out == NULL || outl == 0) return(0);
+       if (b->next_bio == NULL) return(0);
+
+       ret=BIO_read(b->next_bio,out,outl);
+       if (ret > 0)
+               ascii2ebcdic(out,out,ret);
+       return(ret);
+}
+
+static int ebcdic_write(BIO *b, char *in, int inl)
+{
+       EBCDIC_OUTBUFF *wbuf;
+       int ret=0;
+       int num;
+       unsigned char n;
+
+       if ((in == NULL) || (inl <= 0)) return(0);
+       if (b->next_bio == NULL) return(0);
+
+       wbuf=(EBCDIC_OUTBUFF *)b->ptr;
+
+       if (inl > (num = wbuf->alloced))
+       {
+               num = num + num;  /* double the size */
+               if (num < inl)
+                       num = inl;
+               Free((char*)wbuf);
+               wbuf=(EBCDIC_OUTBUFF *)Malloc(sizeof(EBCDIC_OUTBUFF) + num);
+
+               wbuf->alloced = num;
+               wbuf->buff[0] = '\0';
+
+               b->ptr=(char *)wbuf;
+       }
+
+       ebcdic2ascii(wbuf->buff, in, inl);
+
+       ret=BIO_write(b->next_bio, wbuf->buff, inl);
+
+       return(ret);
+}
+
+static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr)
+{
+       long ret;
+
+       if (b->next_bio == NULL) return(0);
+       switch (cmd)
+       {
+       case BIO_CTRL_DUP:
+               ret=0L;
+               break;
+       default:
+               ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+               break;
+       }
+       return(ret);
+}
+
+static int ebcdic_gets(BIO *bp, char *buf, int size)
+{
+       int i, ret;
+       if (bp->next_bio == NULL) return(0);
+/*     return(BIO_gets(bp->next_bio,buf,size));*/
+       for (i=0; i<size-1; ++i)
+       {
+               ret = ebcdic_read(bp,&buf[i],1);
+               if (ret <= 0)
+                       break;
+               else if (buf[i] == '\n')
+               {
+                       ++i;
+                       break;
+               }
+       }
+       if (i < size)
+               buf[i] = '\0';
+       return (ret < 0 && i == 0) ? ret : i;
+}
+
+static int ebcdic_puts(BIO *bp, char *str)
+{
+       if (bp->next_bio == NULL) return(0);
+       return ebcdic_write(bp, str, strlen(str));
+}
+#endif
+
 int MAIN(int argc, char *argv[])
        {
        short port=PORT;
@@ -692,6 +842,9 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                                        print_stats(bio_s_out,SSL_get_SSL_CTX(con));
                                        }
                                }
+#ifdef CHARSET_EBCDIC
+                       ebcdic2ascii(buf,buf,i);
+#endif
                        l=k=0;
                        for (;;)
                                {
@@ -750,6 +903,9 @@ again:
                                switch (SSL_get_error(con,i))
                                        {
                                case SSL_ERROR_NONE:
+#ifdef CHARSET_EBCDIC
+                                       ascii2ebcdic(buf,buf,i);
+#endif
                                        write(fileno(stdout),buf,
                                                (unsigned int)i);
                                        if (SSL_pending(con)) goto again;
@@ -941,6 +1097,9 @@ static int www_body(char *hostname, int s, unsigned char *context)
        /* SSL_set_fd(con,s); */
        BIO_set_ssl(ssl_bio,con,BIO_CLOSE);
        BIO_push(io,ssl_bio);
+#ifdef CHARSET_EBCDIC
+       io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io);
+#endif
 
        if (s_debug)
                {
@@ -1010,7 +1169,7 @@ static int www_body(char *hostname, int s, unsigned char *context)
                        static char *space="                          ";
 
                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
-                       BIO_puts(io,"<HTML><BODY BGCOLOR=ffffff>\n");
+                       BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
                        BIO_puts(io,"<pre>\n");
 /*                     BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
                        BIO_puts(io,"\n");
@@ -1082,7 +1241,7 @@ static int www_body(char *hostname, int s, unsigned char *context)
                        BIO_puts(io,"</BODY></HTML>\r\n\r\n");
                        break;
                        }
-               else if ((www == 2) && (strncmp("GET ",buf,4) == 0))
+               else if ((www == 2) && (strncmp("GET /",buf,5) == 0))
                        {
                        BIO *file;
                        char *p,*e;
index f155434..3c4b957 100644 (file)
@@ -39,7 +39,7 @@ LIBOBJ= cryptlib.o mem.o cversion.o ex_data.o tmdiff.o cpt_err.o
 
 SRC= $(LIBSRC)
 
-EXHEADER= crypto.h tmdiff.h opensslv.h opensslconf.h
+EXHEADER= crypto.h tmdiff.h opensslv.h opensslconf.h ebcdic.h
 HEADER=        cryptlib.h date.h $(EXHEADER)
 
 ALL=    $(GENERAL) $(SRC) $(HEADER)
index 84440cc..226474f 100644 (file)
 
 int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp)
        {
+#ifdef CHARSET_EBCDIC
+       /* KLUDGE! We convert to ascii before writing DER */
+       int len;
+       char tmp[24];
+       ASN1_STRING tmpstr = *(ASN1_STRING *)a;
+
+       len = tmpstr.length;
+       ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
+       tmpstr.data = tmp;
+
+       a = (ASN1_GENERALIZEDTIME *) &tmpstr;
+#endif
        return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
                V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL));
        }
@@ -82,6 +94,9 @@ ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
                ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ERR_R_NESTED_ASN1_ERROR);
                return(NULL);
                }
+#ifdef CHARSET_EBCDIC
+       ascii2ebcdic(ret->data, ret->data, ret->length);
+#endif
        if (!ASN1_GENERALIZEDTIME_check(ret))
                {
                ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ASN1_R_INVALID_TIME_FORMAT);
@@ -202,5 +217,8 @@ ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
                ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
        s->length=strlen(p);
        s->type=V_ASN1_GENERALIZEDTIME;
+#ifdef CHARSET_EBCDIC_not
+       ebcdic2ascii(s->data, s->data, s->length);
+#endif
        return(s);
        }
index 3d76290..cdec7a1 100644 (file)
@@ -95,6 +95,7 @@ int ASN1_PRINTABLE_type(unsigned char *s, int len)
        while ((*s) && (len-- != 0))
                {
                c= *(s++);
+#ifndef CHARSET_EBCDIC
                if (!(  ((c >= 'a') && (c <= 'z')) ||
                        ((c >= 'A') && (c <= 'Z')) ||
                        (c == ' ') ||
@@ -108,6 +109,13 @@ int ASN1_PRINTABLE_type(unsigned char *s, int len)
                        ia5=1;
                if (c&0x80)
                        t61=1;
+#else
+               if (!isalnum(c) && (c != ' ') &&
+                   strchr("'()+,-./:=?", c) == NULL)
+                       ia5=1;
+               if (os_toascii[c] & 0x80)
+                       t61=1;
+#endif
                }
        if (t61) return(V_ASN1_T61STRING);
        if (ia5) return(V_ASN1_IA5STRING);
index 718992d..c1690a5 100644 (file)
 
 int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
        {
+#ifdef CHARSET_EBCDIC
+       /* KLUDGE! We convert to ascii before writing DER */
+       char tmp[24];
+       ASN1_STRING tmpstr;
+
+       if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) {
+           int len;
+
+           tmpstr = *(ASN1_STRING *)a;
+           len = tmpstr.length;
+           ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
+           tmpstr.data = tmp;
+           a = (ASN1_GENERALIZEDTIME *) &tmpstr;
+       }
+#endif
        if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
                                return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
                                     a->type ,V_ASN1_UNIVERSAL));
index 2c605ef..688199f 100644 (file)
 
 int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
        {
+#ifndef CHARSET_EBCDIC
        return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
                V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
+#else
+       /* KLUDGE! We convert to ascii before writing DER */
+       int len;
+       char tmp[24];
+       ASN1_STRING x = *(ASN1_STRING *)a;
+
+       len = x.length;
+       ebcdic2ascii(tmp, x.data, (len >= sizeof tmp) ? sizeof tmp : len);
+       x.data = tmp;
+       return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
+#endif
        }
 
 
@@ -85,6 +97,9 @@ ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
                ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ERR_R_NESTED_ASN1_ERROR);
                return(NULL);
                }
+#ifdef CHARSET_EBCDIC
+       ascii2ebcdic(ret->data, ret->data, ret->length);
+#endif
        if (!ASN1_UTCTIME_check(ret))
                {
                ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ASN1_R_INVALID_TIME_FORMAT);
@@ -238,5 +253,8 @@ ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
                ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
        s->length=strlen(p);
        s->type=V_ASN1_UTCTIME;
+#ifdef CHARSET_EBCDIC_not
+       ebcdic2ascii(s->data, s->data, s->length);
+#endif
        return(s);
        }
index 4d6c9b2..d81c50d 100644 (file)
@@ -117,9 +117,18 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
 
                for (j=0; j<i; j++)
                        {
+#ifndef CHARSET_EBCDIC
                        if (!(  ((buf[j] >= '0') && (buf[j] <= '9')) ||
                                ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
                                ((buf[j] >= 'A') && (buf[j] <= 'F'))))
+#else
+                       /* This #ifdef is not strictly necessary, since
+                        * the characters A...F a...f 0...9 are contiguous
+                        * (yes, even in EBCDIC - but not the whole alphabet).
+                        * Nevertheless, isxdigit() is faster.
+                        */
+                       if (!isxdigit(buf[j]))
+#endif
                                {
                                i=j;
                                break;
index 9bcc5a9..e6e9b9d 100644 (file)
@@ -123,9 +123,18 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
 
                for (j=i-1; j>0; j--)
                        {
+#ifndef CHARSET_EBCDIC
                        if (!(  ((buf[j] >= '0') && (buf[j] <= '9')) ||
                                ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
                                ((buf[j] >= 'A') && (buf[j] <= 'F'))))
+#else
+                       /* This #ifdef is not strictly necessary, since
+                        * the characters A...F a...f 0...9 are contiguous
+                        * (yes, even in EBCDIC - but not the whole alphabet).
+                        * Nevertheless, isxdigit() is faster.
+                        */
+                       if (!isxdigit(buf[j]))
+#endif
                                {
                                i=j;
                                break;
index 517290b..6f26427 100644 (file)
@@ -357,6 +357,7 @@ int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
        c=s;
        for (;;)
                {
+#ifndef CHARSET_EBCDIC
                if (    ((*s == '/') &&
                                ((s[1] >= 'A') && (s[1] <= 'Z') && (
                                        (s[2] == '=') ||
@@ -364,6 +365,15 @@ int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
                                        (s[3] == '='))
                                 ))) ||
                        (*s == '\0'))
+#else
+               if (    ((*s == '/') &&
+                               (isupper(s[1]) && (
+                                       (s[2] == '=') ||
+                                       (isupper(s[2]) &&
+                                       (s[3] == '='))
+                                ))) ||
+                       (*s == '\0'))
+#endif
                        {
                        if ((l <= 0) && !first)
                                {
index 80182c0..5ff14b1 100644 (file)
@@ -72,6 +72,10 @@ int main(int argc, char *argv[])
 #else
 #include <openssl/blowfish.h>
 
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
 char *bf_key[2]={
        "abcdefghijklmnopqrstuvwxyz",
        "Who is John Galt?"
@@ -351,9 +355,16 @@ static int test(void)
        unsigned char out[8]; 
        BF_LONG len;
 
+#ifdef CHARSET_EBCDIC
+       ebcdic2ascii(cbc_data, cbc_data, strlen(cbc_data));
+#endif
+
        printf("testing blowfish in raw ecb mode\n");
        for (n=0; n<2; n++)
                {
+#ifdef CHARSET_EBCDIC
+               ebcdic2ascii(bf_key[n], bf_key[n], strlen(bf_key[n]));
+#endif
                BF_set_key(&key,strlen(bf_key[n]),(unsigned char *)bf_key[n]);
 
                data[0]=bf_plain[n][0];
index 71bbce8..a7cd828 100644 (file)
@@ -102,7 +102,13 @@ int BIO_dump(BIO *bio, const char *s, int len)
       if (((i*DUMP_WIDTH)+j)>=len)
        break;
       ch=((unsigned char)*((char *)(s)+i*DUMP_WIDTH+j)) & 0xff;
+#ifndef CHARSET_EBCDIC
       sprintf(tmp,"%c",((ch>=' ')&&(ch<='~'))?ch:'.');
+#else
+      sprintf(tmp,"%c",((ch>=os_toascii[' '])&&(ch<=os_toascii['~']))
+             ? os_toebcdic[ch]
+             : '.');
+#endif
       strcat(buf,tmp);
     }
     strcat(buf,"\n");
index 4e5644e..f9a015d 100644 (file)
@@ -71,6 +71,7 @@
 #define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \
                                        CONF_PUNCTUATION)
 
+#ifndef CHARSET_EBCDIC
 #define IS_COMMENT(a)          (CONF_COMMENT&(CONF_type[(a)&0x7f]))
 #define IS_EOF(a)              ((a) == '\0')
 #define IS_ESC(a)              ((a) == '\\')
                                (CONF_type[(a)&0x7f]&CONF_ALPHA_NUMERIC_PUNCT)
 #define IS_QUOTE(a)            (CONF_type[(a)&0x7f]&CONF_QUOTE)
 
+#else /*CHARSET_EBCDIC*/
+
+#define IS_COMMENT(a)          (CONF_COMMENT&(CONF_type[os_toascii[a]&0x7f]))
+#define IS_EOF(a)              (os_toascii[a] == '\0')
+#define IS_ESC(a)              (os_toascii[a] == '\\')
+#define IS_NUMER(a)            (CONF_type[os_toascii[a]&0x7f]&CONF_NUMBER)
+#define IS_WS(a)               (CONF_type[os_toascii[a]&0x7f]&CONF_WS)
+#define IS_ALPHA_NUMERIC(a)    (CONF_type[os_toascii[a]&0x7f]&CONF_ALPHA_NUMERIC)
+#define IS_ALPHA_NUMERIC_PUNCT(a) \
+                               (CONF_type[os_toascii[a]&0x7f]&CONF_ALPHA_NUMERIC_PUNCT)
+#define IS_QUOTE(a)            (CONF_type[os_toascii[a]&0x7f]&CONF_QUOTE)
+#endif /*CHARSET_EBCDIC*/
+
 static unsigned short CONF_type[128]={
        0x008,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
        0x000,0x010,0x010,0x000,0x000,0x010,0x000,0x000,
index 283261c..8297b7d 100644 (file)
@@ -70,6 +70,10 @@ extern "C" {
 #include <openssl/stack.h>
 #include <openssl/opensslv.h>
 
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
 /* Backward compatibility to SSLeay */
 /* This is more to be used to check the correct DLL is being used
  * in the MS world. */
index db24541..697167b 100644 (file)
@@ -1,5 +1,13 @@
 /* NOCW */
 #include <stdio.h>
+#ifdef _OSD_POSIX
+#ifndef CHARSET_EBCDIC
+#define CHARSET_EBCDIC 1
+#endif
+#endif
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
 
 /* This version of crypt has been developed from my MIT compatable
  * DES library.
@@ -67,7 +75,37 @@ char *crypt(const char *buf, const char *salt)
        {
        static char buff[14];
 
+#ifndef CHARSET_EBCDIC
        return(des_fcrypt(buf,salt,buff));
+#else
+       char e_salt[2+1];
+       char e_buf[32+1];       /* replace 32 by 8 ? */
+       char *ret;
+
+       /* Copy at most 2 chars of salt */
+       if ((e_salt[0] = salt[0]) != '\0')
+           e_salt[1] = salt[1];
+
+       /* Copy at most 32 chars of password */
+       strncpy (e_buf, buf, sizeof(e_buf));
+
+       /* Make sure we have a delimiter */
+       e_salt[sizeof(e_salt)-1] = e_buf[sizeof(e_buf)-1] = '\0';
+
+       /* Convert the e_salt to ASCII, as that's what des_fcrypt works on */
+       ebcdic2ascii(e_salt, e_salt, sizeof e_salt);
+
+       /* Convert the cleartext password to ASCII */
+       ebcdic2ascii(e_buf, e_buf, sizeof e_buf);
+
+       /* Encrypt it (from/to ASCII) */
+       ret = des_fcrypt(e_buf,e_salt,buff);
+
+       /* Convert the result back to EBCDIC */
+       ascii2ebcdic(ret, ret, strlen(ret));
+       
+       return ret;
+#endif
        }
 
 
@@ -90,10 +128,17 @@ char *des_fcrypt(const char *buf, const char *salt, char *ret)
         * crypt to "*".  This was found when replacing the crypt in
         * our shared libraries.  People found that the disbled
         * accounts effectivly had no passwd :-(. */
+#ifndef CHARSET_EBCDIC
        x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
        Eswap0=con_salt[x]<<2;
        x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
        Eswap1=con_salt[x]<<6;
+#else
+       x=ret[0]=((salt[0] == '\0')?os_toascii['A']:salt[0]);
+       Eswap0=con_salt[x]<<2;
+       x=ret[1]=((salt[1] == '\0')?os_toascii['A']:salt[1]);
+       Eswap1=con_salt[x]<<6;
+#endif
 
 /* EAY
 r=strlen(buf);
index 47bc5fa..e028e4c 100644 (file)
@@ -246,6 +246,25 @@ void ERR_put_error(int lib, int func, int reason, const char *file,
        {
        ERR_STATE *es;
 
+#ifdef _OSD_POSIX
+       /* In the BS2000-OSD POSIX subsystem, the compiler generates
+        * path names in the form "*POSIX(/etc/passwd)".
+        * This dirty hack strips them to something sensible.
+        * @@@ We shouldn't modify a const string, though.
+        */
+       if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
+               char *end;
+
+               /* Skip the "*POSIX(" prefix */
+               file += sizeof("*POSIX(")-1;
+               end = &file[strlen(file)-1];
+               if (*end == ')')
+                       *end = '\0';
+               /* Optional: use the basename of the path only. */
+               if ((end = strrchr(file, '/')) != NULL)
+                       file = &end[1];
+       }
+#endif
        es=ERR_get_state();
 
        es->top=(es->top+1)%ERR_NUM_ERRORS;
index 20d6ec6..0152624 100644 (file)
 #include "cryptlib.h"
 #include <openssl/evp.h>
 
+#ifndef CHARSET_EBCDIC
 #define conv_bin2ascii(a)      (data_bin2ascii[(a)&0x3f])
 #define conv_ascii2bin(a)      (data_ascii2bin[(a)&0x7f])
+#else
+/* We assume that PEM encoded files are EBCDIC files
+ * (i.e., printable text files). Convert them here while decoding.
+ * When encoding, output is EBCDIC (text) format again.
+ * (No need for conversion in the conv_bin2ascii macro, as the
+ * underlying textstring data_bin2ascii[] is already EBCDIC)
+ */
+#define conv_bin2ascii(a)      (data_bin2ascii[(a)&0x3f])
+#define conv_ascii2bin(a)      (data_ascii2bin[os_toascii[a]&0x7f])
+#endif
 
 /* 64 char lines
  * pad input with 0
index 15eb0c4..9a67dff 100644 (file)
@@ -69,6 +69,10 @@ int main(int argc, char *argv[])
 #else
 #include <openssl/hmac.h>
 
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
 struct test_st
        {
        unsigned char key[16];
@@ -116,6 +120,13 @@ int main(int argc, char *argv[])
        int i,err=0;
        char *p;
 
+#ifdef CHARSET_EBCDIC
+       ebcdic2ascii(test[0].data, test[0].data, test[0].data_len);
+       ebcdic2ascii(test[1].data, test[1].data, test[1].data_len);
+       ebcdic2ascii(test[2].key,  test[2].key,  test[2].key_len);
+       ebcdic2ascii(test[2].data, test[2].data, test[2].data_len);
+#endif
+
        for (i=0; i<4; i++)
                {
                p=pt(HMAC(EVP_md5(),
index 17b288b..7157299 100644 (file)
@@ -70,7 +70,23 @@ unsigned char *MD2(unsigned char *d, unsigned long n, unsigned char *md)
 
        if (md == NULL) md=m;
        MD2_Init(&c);
+#ifndef CHARSET_EBCDIC
        MD2_Update(&c,d,n);
+#else
+       {
+               char temp[1024];
+               unsigned long chunk;
+
+               while (n > 0)
+               {
+                       chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
+                       ebcdic2ascii(temp, d, chunk);
+                       MD2_Update(&c,temp,chunk);
+                       n -= chunk;
+                       d += chunk;
+               }
+       }
+#endif
        MD2_Final(md,&c);
        memset(&c,0,sizeof(c)); /* Security consideration */
        return(md);
index 63404b1..461d124 100644 (file)
@@ -69,6 +69,10 @@ int main(int argc, char *argv[])
 #else
 #include <openssl/md2.h>
 
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
 char *test[]={
        "",
        "a",
index ef65a1d..7ed0024 100644 (file)
 
 void do_fp(FILE *f);
 void pt(unsigned char *md);
+#ifndef _OSD_POSIX
 int read(int, void *, unsigned int);
+#endif
+
 int main(int argc, char **argv)
        {
        int i,err=0;
index c98721f..4b10e7f 100644 (file)
 #include <string.h>
 #include <openssl/md5.h>
 
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
 unsigned char *MD5(unsigned char *d, unsigned long n, unsigned char *md)
        {
        MD5_CTX c;
@@ -67,7 +71,23 @@ unsigned char *MD5(unsigned char *d, unsigned long n, unsigned char *md)
 
        if (md == NULL) md=m;
        MD5_Init(&c);
+#ifndef CHARSET_EBCDIC
        MD5_Update(&c,d,n);
+#else
+       {
+               char temp[1024];
+               unsigned long chunk;
+
+               while (n > 0)
+               {
+                       chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
+                       ebcdic2ascii(temp, d, chunk);
+                       MD5_Update(&c,temp,chunk);
+                       n -= chunk;
+                       d += chunk;
+               }
+       }
+#endif
        MD5_Final(md,&c);
        memset(&c,0,sizeof(c)); /* security consideration */
        return(md);
index 6fc6c0e..0b1134b 100644 (file)
@@ -73,6 +73,10 @@ int main(int argc, char *argv[])
 #else
 #include <openssl/mdc2.h>
 
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
 static unsigned char pad1[16]={
        0x42,0xE5,0x0C,0xD2,0x24,0xBA,0xCE,0xBA,
        0x76,0x0B,0xDD,0x2B,0xD4,0x09,0x28,0x1A
@@ -91,6 +95,10 @@ int main(int argc, char *argv[])
        MDC2_CTX c;
        static char *text="Now is the time for all ";
 
+#ifdef CHARSET_EBCDIC
+       ebcdic2ascii(text,text,strlen(text));
+#endif
+
        MDC2_Init(&c);
        MDC2_Update(&c,(unsigned char *)text,strlen(text));
        MDC2_Final(&(md[0]),&c);
index 0b24b14..d56edcd 100644 (file)
@@ -497,6 +497,17 @@ char *OBJ_bsearch(char *key, char *base, int num, int size, int (*cmp)())
                else
                        return(p);
                }
+#ifdef CHARSET_EBCDIC
+/* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and
+ * I don't have perl (yet), we revert to a *LINEAR* search
+ * when the object wasn't found in the binary search.
+ */
+       for (i=0; i<num; ++i) {
+               p= &(base[i*size]);
+               if ((*cmp)(key,p) == 0)
+                       return p;
+       }
+#endif
        return(NULL);
        }
 
index 2446430..f1693ac 100644 (file)
@@ -286,6 +286,10 @@ int PEM_ASN1_write_bio(int (*i2d)(), const char *name, BIO *bp, char *x,
                                PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY);
                                goto err;
                                }
+#ifdef CHARSET_EBCDIC
+                       /* Convert the pass phrase from EBCDIC */
+                       ebcdic2ascii(buf, buf, klen);
+#endif
                        kstr=(unsigned char *)buf;
                        }
                RAND_seed(data,i);/* put in the RSA key. */
@@ -345,6 +349,11 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
                PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_PASSWORD_READ);
                return(0);
                }
+#ifdef CHARSET_EBCDIC
+       /* Convert the pass phrase from EBCDIC */
+       ebcdic2ascii(buf, buf, klen);
+#endif
+
        EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
                (unsigned char *)buf,klen,1,key,NULL);
 
@@ -394,9 +403,15 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
        for (;;)
                {
                c= *header;
+#ifndef CHARSET_EBCDIC
                if (!(  ((c >= 'A') && (c <= 'Z')) || (c == '-') ||
                        ((c >= '0') && (c <= '9'))))
                        break;
+#else
+               if (!(  isupper(c) || (c == '-') ||
+                       isdigit(c)))
+                       break;
+#endif
                header++;
                }
        *header='\0';
index 8481e44..4f8b88a 100644 (file)
 
 void do_fp(FILE *f);
 void pt(unsigned char *md);
+#ifndef _OSD_POSIX
 int read(int, void *, unsigned int);
+#endif
+
 int main(int argc, char **argv)
        {
        int i,err=0;
index 8a19f29..5e93d46 100644 (file)
@@ -69,6 +69,10 @@ int main(int argc, char *argv[])
 #else
 #include <openssl/ripemd.h>
 
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
 char *test[]={
        "",
        "a",
@@ -104,6 +108,9 @@ int main(int argc, char *argv[])
        i=1;
        while (*P != NULL)
                {
+#ifdef CHARSET_EBCDIC
+               ebcdic2ascii((char *)*P, (char *)*P, strlen((char *)*P));
+#endif
                p=pt(RIPEMD160(&(P[0][0]),(unsigned long)strlen((char *)*P),NULL));
                if (strcmp(p,(char *)*R) != 0)
                        {
index 3c81a96..d350c88 100644 (file)
 
 void do_fp(FILE *f);
 void pt(unsigned char *md);
+#ifndef _OSD_POSIX
 int read(int, void *, unsigned int);
+#endif
+
 int main(int argc, char **argv)
        {
        int i,err=0;
index 6a34a9a..9400ad2 100644 (file)
@@ -69,6 +69,10 @@ int main(int argc, char *argv[])
 #else
 #include <openssl/sha.h>
 
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
 #undef SHA_0 /* FIPS 180 */
 #define  SHA_1 /* FIPS 180-1 */
 
@@ -105,6 +109,11 @@ int main(int argc, char *argv[])
        SHA_CTX c;
        unsigned char md[SHA_DIGEST_LENGTH];
 
+#ifdef CHARSET_EBCDIC
+       ebcdic2ascii(test[0], test[0], strlen(test[0]));
+       ebcdic2ascii(test[1], test[1], strlen(test[1]));
+#endif
+
        P=(unsigned char **)test;
        R=(unsigned char **)ret;
        i=1;
@@ -125,6 +134,9 @@ int main(int argc, char *argv[])
                }
 
        memset(buf,'a',1000);
+#ifdef CHARSET_EBCDIC
+       ebcdic2ascii(buf, buf, 1000);
+#endif /*CHARSET_EBCDIC*/
        SHA1_Init(&c);
        for (i=0; i<1000; i++)
                SHA1_Update(&c,buf,1000);
index 6ebcbb1..2b0744d 100644 (file)
@@ -69,6 +69,10 @@ int main(int argc, char *argv[])
 #else
 #include <openssl/sha.h>
 
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
 #define SHA_0 /* FIPS 180 */
 #undef  SHA_1 /* FIPS 180-1 */
 
@@ -105,6 +109,11 @@ int main(int argc, char *argv[])
        SHA_CTX c;
        unsigned char md[SHA_DIGEST_LENGTH];
 
+#ifdef CHARSET_EBCDIC
+       ebcdic2ascii(test[0], test[0], strlen(test[0]));
+       ebcdic2ascii(test[1], test[1], strlen(test[1]));
+#endif
+
        P=(unsigned char **)test;
        R=(unsigned char **)ret;
        i=1;
@@ -125,6 +134,9 @@ int main(int argc, char *argv[])
                }
 
        memset(buf,'a',1000);
+#ifdef CHARSET_EBCDIC
+       ebcdic2ascii(buf, buf, 1000);
+#endif /*CHARSET_EBCDIC*/
        SHA_Init(&c);
        for (i=0; i<1000; i++)
                SHA_Update(&c,buf,1000);
index b283a62..691b71f 100644 (file)
@@ -75,6 +75,9 @@ int i;
        static char hex[17]="0123456789ABCDEF";
        int gs_doit[4];
        char tmp_buf[80];
+#ifdef CHARSET_EBCDIC
+       char ebcdic_buf[1024];
+#endif
 
        if (buf == NULL)
                {
@@ -110,6 +113,19 @@ int i;
                type=ne->value->type;
                num=ne->value->length;
                q=ne->value->data;
+#ifdef CHARSET_EBCDIC
+                if (type == V_ASN1_GENERALSTRING ||
+                   type == V_ASN1_VISIBLESTRING ||
+                   type == V_ASN1_PRINTABLESTRING ||
+                   type == V_ASN1_TELETEXSTRING ||
+                   type == V_ASN1_VISIBLESTRING ||
+                   type == V_ASN1_IA5STRING) {
+                        ascii2ebcdic(ebcdic_buf, q,
+                                    (num > sizeof ebcdic_buf)
+                                    ? sizeof ebcdic_buf : num);
+                        q=ebcdic_buf;
+               }
+#endif
 
                if ((type == V_ASN1_GENERALSTRING) && ((num%4) == 0))
                        {
@@ -132,7 +148,12 @@ int i;
                        {
                        if (!gs_doit[j&3]) continue;
                        l2++;
+#ifndef CHARSET_EBCDIC
                        if ((q[j] < ' ') || (q[j] > '~')) l2+=3;
+#else
+                       if ((os_toascii[q[j]] < os_toascii[' ']) ||
+                           (os_toascii[q[j]] > os_toascii['~'])) l2+=3;
+#endif
                        }
 
                lold=l;
@@ -152,11 +173,14 @@ int i;
                memcpy(p,s,(unsigned int)l1); p+=l1;
                *(p++)='=';
 
+#ifndef CHARSET_EBCDIC /* q was assigned above already. */
                q=ne->value->data;
+#endif
 
                for (j=0; j<num; j++)
                        {
                        if (!gs_doit[j&3]) continue;
+#ifndef CHARSET_EBCDIC
                        n=q[j];
                        if ((n < ' ') || (n > '~'))
                                {
@@ -167,6 +191,19 @@ int i;
                                }
                        else
                                *(p++)=n;
+#else
+                       n=os_toascii[q[j]];
+                       if ((n < os_toascii[' ']) ||
+                           (n > os_toascii['~']))
+                               {
+                               *(p++)='\\';
+                               *(p++)='x';
+                               *(p++)=hex[(n>>4)&0x0f];
+                               *(p++)=hex[n&0x0f];
+                               }
+                       else
+                               *(p++)=q[j];
+#endif
                        }
                *p='\0';
                }