]> andersk Git - moira.git/blob - util/gdss/lib/rgdss.c
add parens to make operator precedence work right, and pacify gcc
[moira.git] / util / gdss / lib / rgdss.c
1 /*
2  * $Source$
3  * $Author$
4  * $Header$
5  */
6 /*
7  * GDSS The Generic Digital Signature Service
8  *
9  * rgdss.c: Raw signature signing and verification routines.
10  */
11
12 #include <BigNum.h>
13 #include <BigRSA.h>
14 #include <krb.h>
15 #include <gdss.h>
16 #include <stdio.h>
17 #include <time.h>
18
19 int gdss_rsign(signature, hash, name, instance, realm, key)
20 unsigned char *signature;
21 unsigned char *hash;
22 char *name;
23 char *instance;
24 char *realm;
25 RSAKeyStorage *key;
26 {
27   unsigned char *cp, *ip;
28   time_t the_time;
29   register int i;
30   register int status;
31   int loopcnt;
32   int siglen;
33
34   for (loopcnt = 0; loopcnt < 10; loopcnt++) {
35     cp = signature;
36     for (i = 0; i < 16; i++)
37       *cp++ = hash[i];
38     *cp++ = 0x44;   /* Version Number */
39     ip = (unsigned char *) name;
40     while (*cp++ = *ip++);
41     ip = (unsigned char *) instance;
42     while (*cp++ = *ip++);
43     ip = (unsigned char *) realm;
44     while (*cp++ = *ip++);
45     time(&the_time);
46     *cp++ = ((the_time) >> 24) & 0xff;
47     *cp++ = ((the_time) >> 16) & 0xff;
48     *cp++ = ((the_time) >> 8) & 0xff;
49     *cp++ = the_time & 0xff;
50     if(!RSASign(signature, cp - signature, key, &signature[cp - signature],
51                 &siglen)) return (-1);
52     status = gdss_rpadout(&signature[16], cp - signature + siglen - 16);
53     if ((status == GDSS_SUCCESS) || (status != GDSS_E_PADTOOMANY)) {
54       ip = &signature[16];
55       cp = signature;
56       while (*cp++ = *ip++);    /* shuffle over hash */
57       return(GDSS_SUCCESS);
58     }
59     sleep(1);                   /* Allow time to change */
60   }
61   return (GDSS_E_PADTOOMANY);
62 }
63
64 /* gdss_rpadout: Remove null bytes from signature by replacing them with
65    the sequence GDSS_ESCAPE, GDSS_NULL. Keep track of how much bigger
66    the signature block is getting and abort if too many bytes (more than
67    GDSS_PAD) would be required.
68 */
69
70 int gdss_rpadout(signature, siglen)
71 unsigned char *signature;
72 int siglen;
73 {
74   register unsigned char *cp;
75   register unsigned char *bp;
76   unsigned char *buf;
77   register int i;
78   register int c;
79   buf = (unsigned char *)malloc(siglen + GDSS_PAD + 1); /* 1 for the null! */
80   if (buf == NULL) return (GDSS_E_ALLOC);
81   memset(buf, 0, siglen + GDSS_PAD + 1); /* Just to be safe */
82   bp = buf;
83   cp = signature;
84   c = 0;
85   for (i = 0; i < siglen; i++) {
86     if ((*cp != '\0') && (*cp != GDSS_ESCAPE)) {
87       *bp++ = *cp++;
88       continue;
89     }
90     if (c++ > GDSS_PAD) {
91       free(buf);                /* Don't have to zeroize, nothing
92                                    confidential */
93       return (GDSS_E_PADTOOMANY);
94     }
95     *bp++ = GDSS_ESCAPE;
96     *bp++ = (*cp == '\0') ? GDSS_NULL : GDSS_ESCAPE;
97     cp++;
98   }
99   *bp++ = '\0';                 /* Null Terminate */
100   memcpy(signature, buf, bp - buf);
101   free(buf);
102   return (GDSS_SUCCESS);
103 }
104   
105 int gdss_rpadin(signature, outlen)
106 unsigned char *signature;
107 int *outlen;
108 {
109   unsigned char *buf;
110   register unsigned char *cp;
111   register unsigned char *bp;
112   buf = (unsigned char *) malloc(strlen(signature));
113   if (buf == NULL) return (GDSS_E_ALLOC);
114   bp = buf;
115   cp = signature;
116   while (*cp) {
117     if (*cp != GDSS_ESCAPE) {
118       *bp++ = *cp++;
119       continue;
120     }
121     if (*(++cp) == GDSS_NULL) {
122       *bp++ = '\0';
123     } else *bp++ = GDSS_ESCAPE;
124     if(!*cp++) break;
125   }
126   *outlen = bp - buf;
127   memcpy(signature, buf, *outlen);
128   free (buf);
129   return (GDSS_SUCCESS);
130 }
131
132 int gdss_rverify(isignature, hash, name, instance,
133                  realm, key, the_time, rawsig)
134 unsigned char *isignature;
135 unsigned char *hash;
136 char *name;
137 char *instance;
138 char *realm;
139 RSAKeyStorage *key;
140 unsigned int *the_time;
141 unsigned char *rawsig;
142 {
143   unsigned char *cp;
144   char *ip;
145   register int i;
146   int status;
147   int siglen;
148   unsigned char *signature;
149
150   if (*isignature != 0x44) return (GDSS_E_BVERSION); /* Bad Version */
151
152   signature = (unsigned char *) malloc (strlen(isignature) + 17);
153         /* Length of input signature + null byte + 16 bytes of hash */
154   strcpy(&signature[16], isignature);
155
156   status = gdss_rpadin(&signature[16], &siglen);
157   if (status) return (status);
158   
159   siglen += 16;                 /* Account for the hash */
160   cp = signature;
161   for (i = 0; i < 16; i++)
162     *cp++ = hash[i];
163   if (*cp++ != 0x44) return (GDSS_E_BVERSION); /* Bad Version */
164   ip = name;
165   while ((*ip++ = *cp++) && (ip < name + ANAME_SZ));
166   ip = instance;
167   while ((*ip++ = *cp++) && (ip < instance + INST_SZ));
168   ip = realm;
169   while ((*ip++ = *cp++) && (ip < realm + REALM_SZ));
170   *the_time = 0;
171   *the_time |= *cp++ << 24;
172   *the_time |= *cp++ << 16;
173   *the_time |= *cp++ << 8;
174   *the_time |= *cp++;
175   if(!RSAVerify(signature, cp - signature, key, &signature[cp - signature],
176                 siglen - (cp - signature))) {
177     free (signature);
178     return (GDSS_E_BADSIG);
179   }
180   if (rawsig == NULL) {
181     free (signature);
182     return (GDSS_SUCCESS);
183   }
184   memcpy(rawsig, &signature[cp - signature], siglen - (cp - signature));
185   status = gdss_rpadout(rawsig, siglen - (cp - signature));
186   free (signature);
187   return (status);
188 }
189     
190 gdss_recompose(aSigInfo, signature)
191 SigInfo *aSigInfo;
192 unsigned char *signature;
193 {
194   register unsigned char *ip;
195   register unsigned char *cp;
196   unsigned char *isignature;
197   int siglen;
198   int status;
199
200   isignature = (unsigned char *) malloc(strlen(aSigInfo->rawsig) + 1);
201   if (isignature == NULL) return (GDSS_E_ALLOC);
202   strcpy(isignature, aSigInfo->rawsig);
203   status = gdss_rpadin(isignature, &siglen);
204   if (status) {
205     free(isignature);
206     return (status);
207   }
208
209   cp = signature;
210   *cp++ = 0x44;                 /* Version */
211   ip = (unsigned char *) aSigInfo->pname;
212   while (*cp++ = *ip++);
213   ip = (unsigned char *) aSigInfo->pinst;
214   while (*cp++ = *ip++);
215   ip = (unsigned char *) aSigInfo->prealm;
216   while (*cp++ = *ip++);
217   *cp++ = ((aSigInfo->timestamp) >> 24) & 0xff;
218   *cp++ = ((aSigInfo->timestamp) >> 16) & 0xff;
219   *cp++ = ((aSigInfo->timestamp) >> 8) & 0xff;
220   *cp++ = aSigInfo->timestamp & 0xff;
221   memcpy(cp, isignature, siglen);
222   free(isignature);
223   return(gdss_rpadout(signature, cp - signature + siglen));
224 }
This page took 0.365497 seconds and 5 git commands to generate.