]> git.sur5r.net Git - openldap/blob - clients/ud/string_to_key.c
Merge in latest from -current.
[openldap] / clients / ud / string_to_key.c
1 #if defined(KERBEROS) && !defined(openbsd)
2 /*
3  * $Source: /repo/OpenLDAP/pkg/ldap/clients/ud/string_to_key.c,v $
4  * $Author: kurt $
5  *
6  * Copyright 1985, 1986, 1987, 1988, 1989 by the Massachusetts Institute
7  * of Technology.
8  *
9  * For copying and distribution information, please see the file
10  * <mit-copyright.h>.
11  *
12  * These routines perform encryption and decryption using the DES
13  * private key algorithm, or else a subset of it-- fewer inner loops.
14  * (AUTH_DES_ITER defaults to 16, may be less.)
15  *
16  * Under U.S. law, this software may not be exported outside the US
17  * without license from the U.S. Commerce department.
18  *
19  * The key schedule is passed as an arg, as well as the cleartext or
20  * ciphertext.  The cleartext and ciphertext should be in host order.
21  *
22  * These routines form the library interface to the DES facilities.
23  *
24  *      spm     8/85    MIT project athena
25  */
26
27 #ifdef KERBEROS_V
28 #include <kerberosIV/mit-copyright.h>
29 #include <kerberosIV/des.h>
30 #else
31 #include <mit-copyright.h>
32 #include <des.h>
33 #endif /* KERBEROS_V */
34
35 #include <stdio.h>
36
37 /* #include "des_internal.h" */
38 #if 1
39 #ifdef KERBEROS_V
40 #include <kerberosIV/krb.h>
41 #else
42 #include <krb.h>
43 #endif /* KERBEROS_V */
44 #endif /* 1 */
45
46 extern int des_debug;
47 extern int des_debug_print();
48 extern void des_fixup_key_parity();
49
50 #ifndef AFSKERBEROS
51 #define WORLDPEACEINOURTIME
52 #endif
53
54 #if defined(WORLDPEACEINOURTIME) /* Use original, not ifs version */
55 #ifndef KERBEROS_V
56 /*
57  * convert an arbitrary length string to a DES key
58  */
59 int
60 des_string_to_key(str,key)
61     char *str;
62     register des_cblock *key;
63 {
64     register char *in_str;
65     register unsigned temp,i;
66     register int j;
67     register long length;
68     static unsigned char *k_p;
69     static int forward;
70     register char *p_char;
71     static char k_char[64];
72     static des_key_schedule key_sked;
73     extern unsigned long des_cbc_cksum();
74
75     in_str = str;
76     forward = 1;
77     p_char = k_char;
78     length = strlen(str);
79
80     /* init key array for bits */
81     memset(k_char, 0, sizeof(k_char));
82
83 #ifdef DEBUG
84     if (des_debug)
85         fprintf(stdout,
86                 "\n\ninput str length = %d  string = %s\nstring = 0x ",
87                 length,str);
88 #endif
89
90     /* get next 8 bytes, strip parity, xor */
91     for (i = 1; i <= length; i++) {
92         /* get next input key byte */
93         temp = (unsigned int) *str++;
94 #ifdef DEBUG
95         if (des_debug)
96             fprintf(stdout,"%02x ",temp & 0xff);
97 #endif
98         /* loop through bits within byte, ignore parity */
99         for (j = 0; j <= 6; j++) {
100             if (forward)
101                 *p_char++ ^= (int) temp & 01;
102             else
103                 *--p_char ^= (int) temp & 01;
104             temp = temp >> 1;
105         } while (--j > 0);
106
107         /* check and flip direction */
108         if ((i%8) == 0)
109             forward = !forward;
110     }
111
112     /* now stuff into the key des_cblock, and force odd parity */
113     p_char = k_char;
114     k_p = (unsigned char *) key;
115
116     for (i = 0; i <= 7; i++) {
117         temp = 0;
118         for (j = 0; j <= 6; j++)
119             temp |= *p_char++ << (1+j);
120         *k_p++ = (unsigned char) temp;
121     }
122
123     /* fix key parity */
124     des_fixup_key_parity(key);
125
126     /* Now one-way encrypt it with the folded key */
127     (void) des_key_sched(key,key_sked);
128     (void) des_cbc_cksum((des_cblock *)in_str,key,length,key_sked,key);
129     /* erase key_sked */
130     memset((char *)key_sked, 0, sizeof(key_sked));
131
132     /* now fix up key parity again */
133     des_fixup_key_parity(key);
134
135     if (des_debug)
136         fprintf(stdout,
137                 "\nResulting string_to_key = 0x%x 0x%x\n",
138                 *((unsigned long *) key),
139                 *((unsigned long *) key+1));
140 }
141
142 #endif /* KERBEROS_V */
143 #else /* Use ifs version */
144
145 #if 0
146 #include <stdio.h>
147     /* These two needed for rxgen output to work */
148 #include <sys/types.h>
149 #include <rx/xdr.h>
150 #include <afs/cellconfig.h>
151 #include <afs/auth.h>
152
153 #include "/usr/andy/kauth/kauth.h"
154 #include "/usr/andy/kauth/kautils.h"
155 #endif
156
157 /* This defines the Andrew string_to_key function.  It accepts a password
158    string as input and converts its via a one-way encryption algorithm to a DES
159    encryption key.  It is compatible with the original Andrew authentication
160    service password database. */
161
162 static void Andrew_StringToKey (str, cell, key)
163   char          *str;
164   char          *cell;                  /* cell for password */
165   des_cblock *key;
166 {   char  password[8+1];                /* crypt is limited to 8 chars anyway */
167     int   i;
168     int   passlen;
169
170     memset(key, 0, sizeof(des_cblock));
171     memset(password, 0, sizeof(password));
172
173     strncpy (password, cell, 8);
174     passlen = strlen (str);
175     if (passlen > 8) passlen = 8;
176
177     for (i=0; i<passlen; i++)
178         password[i] = str[i] ^ cell[i];
179
180     for (i=0;i<8;i++)
181         if (password[i] == '\0') password[i] = 'X';
182
183     /* crypt only considers the first 8 characters of password but for some
184        reason returns eleven characters of result (plus the two salt chars). */
185     strncpy(key, crypt(password, "#~") + 2, sizeof(des_cblock));
186
187     /* parity is inserted into the LSB so leftshift each byte up one bit.  This
188        allows ascii characters with a zero MSB to retain as much significance
189        as possible. */
190     {   char *keybytes = (char *)key;
191         unsigned int temp;
192
193         for (i = 0; i < 8; i++) {
194             temp = (unsigned int) keybytes[i];
195             keybytes[i] = (unsigned char) (temp << 1);
196         }
197     }
198     des_fixup_key_parity (key);
199 }
200
201 static void StringToKey (str, cell, key)
202   char          *str;
203   char          *cell;                  /* cell for password */
204   des_cblock *key;
205 {   des_key_schedule schedule;
206     char temp_key[8];
207     char ivec[8];
208     char password[BUFSIZ];
209     int  passlen;
210
211     strncpy (password, str, sizeof(password));
212     if ((passlen = strlen (password)) < sizeof(password)-1)
213         strncat (password, cell, sizeof(password)-passlen);
214     if ((passlen = strlen(password)) > sizeof(password)) passlen = sizeof(password);
215
216     memcpy(ivec, "kerberos", 8);
217     memcpy(temp_key, "kerberos", 8);
218     des_fixup_key_parity (temp_key);
219     des_key_sched (temp_key, schedule);
220     des_cbc_cksum (password, ivec, passlen, schedule, ivec);
221
222     memcpy(temp_key, ivec, 8);
223     des_fixup_key_parity (temp_key);
224     des_key_sched (temp_key, schedule);
225     des_cbc_cksum (password, key, passlen, schedule, ivec);
226
227     des_fixup_key_parity (key);
228 }
229
230 /* static */  void
231 ka_StringToKey (str, cell, key)
232   char          *str;
233   char          *cell;                  /* cell for password */
234   des_cblock    *key;
235 {   char  realm[REALM_SZ];
236
237 #if NOWAYOUTTODAY
238     long  code;
239     /* code = ka_CellToRealm (cell, realm, 0/*local*/); */
240     if (code) strcpy (realm, "");
241     else lcstring (realm, realm, sizeof(realm)); /* for backward compatibility */
242 #else
243         (void)strcpy(realm, cell);
244 #endif
245
246     if (strlen(str) > 8) StringToKey (str, realm, key);
247     else Andrew_StringToKey (str, realm, key);
248 }
249
250 /*
251  * convert an arbitrary length string to a DES key
252  */
253 int
254 des_string_to_key(str,key)
255     char *str;
256     register des_cblock *key;
257 {
258         /* NB: i should probably call routine to get local cell here */
259         ka_StringToKey(str, "umich.edu", key);
260         return 0;
261 }
262
263 #endif /* Use IFS Version */
264
265 #endif /* kerberos */