]> andersk Git - moira.git/blob - util/gdss/lib/rgdss.c
initial import of gdss from the Athena source tree
[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, *ip;
144   register int i;
145   int status;
146   int siglen;
147   unsigned char *signature;
148
149   if (*isignature != 0x44) return (GDSS_E_BVERSION); /* Bad Version */
150
151   signature = (unsigned char *) malloc (strlen(isignature) + 17);
152         /* Length of input signature + null byte + 16 bytes of hash */
153   strcpy(&signature[16], isignature);
154
155   status = gdss_rpadin(&signature[16], &siglen);
156   if (status) return (status);
157   
158   siglen += 16;                 /* Account for the hash */
159   cp = signature;
160   for (i = 0; i < 16; i++)
161     *cp++ = hash[i];
162   if (*cp++ != 0x44) return (GDSS_E_BVERSION); /* Bad Version */
163   ip = (unsigned char *) name;
164   while (*ip++ = *cp++);
165   ip = (unsigned char *) instance;
166   while (*ip++ = *cp++);
167   ip = (unsigned char *) realm;
168   while (*ip++ = *cp++);
169   *the_time = 0;
170   *the_time |= *cp++ << 24;
171   *the_time |= *cp++ << 16;
172   *the_time |= *cp++ << 8;
173   *the_time |= *cp++;
174   if(!RSAVerify(signature, cp - signature, key, &signature[cp - signature],
175                 siglen - (cp - signature))) {
176     free (signature);
177     return (GDSS_E_BADSIG);
178   }
179   if (rawsig == NULL) {
180     free (signature);
181     return (GDSS_SUCCESS);
182   }
183   memcpy(rawsig, &signature[cp - signature], siglen - (cp - signature));
184   status = gdss_rpadout(rawsig, siglen - (cp - signature));
185   free (signature);
186   return (status);
187 }
188     
189 gdss_recompose(aSigInfo, signature)
190 SigInfo *aSigInfo;
191 unsigned char *signature;
192 {
193   register unsigned char *ip;
194   register unsigned char *cp;
195   unsigned char *isignature;
196   int siglen;
197   int status;
198
199   isignature = (unsigned char *) malloc(strlen(aSigInfo->rawsig) + 1);
200   if (isignature == NULL) return (GDSS_E_ALLOC);
201   strcpy(isignature, aSigInfo->rawsig);
202   status = gdss_rpadin(isignature, &siglen);
203   if (status) {
204     free(isignature);
205     return (status);
206   }
207
208   cp = signature;
209   *cp++ = 0x44;                 /* Version */
210   ip = (unsigned char *) aSigInfo->pname;
211   while (*cp++ = *ip++);
212   ip = (unsigned char *) aSigInfo->pinst;
213   while (*cp++ = *ip++);
214   ip = (unsigned char *) aSigInfo->prealm;
215   while (*cp++ = *ip++);
216   *cp++ = ((aSigInfo->timestamp) >> 24) & 0xff;
217   *cp++ = ((aSigInfo->timestamp) >> 16) & 0xff;
218   *cp++ = ((aSigInfo->timestamp) >> 8) & 0xff;
219   *cp++ = aSigInfo->timestamp & 0xff;
220   memcpy(cp, isignature, siglen);
221   free(isignature);
222   return(gdss_rpadout(signature, cp - signature + siglen));
223 }
This page took 0.062457 seconds and 5 git commands to generate.