7 * GDSS The Generic Digital Signature Service
9 * gdss.c: Main interface routines
18 static RSAKeyStorage gdss_pubkey;
19 static int gdss_have_key;
20 static int pfetchkey();
23 /* This function is obsolete */
24 int GDSS_Sig_Info(Signature, aSigInfo)
25 unsigned char *Signature;
29 static int pfetchkey();
30 unsigned char hash[16];
33 cp = aSigInfo->rawsig;
34 memset(aSigInfo, 0, sizeof(SigInfo));
35 aSigInfo->rawsig = cp;
36 aSigInfo->SigInfoVersion = 0;
40 status = gdss_rverify(Signature, hash, &(*aSigInfo).pname,
41 &(*aSigInfo).pinst, &(*aSigInfo).prealm,
42 &gdss_pubkey, &(*aSigInfo).timestamp,
49 int GDSS_Verify(Data, DataLen, Signature, aSigInfo)
52 unsigned char *Signature;
55 unsigned char hash[16];
56 SigInfo bSigInfo, *iSigInfo;
60 if (aSigInfo == NULL) {
66 if (status) return (status);
68 memset(&bSigInfo, 0, sizeof(bSigInfo));
69 cp = iSigInfo->rawsig;
70 memset(iSigInfo, 0, sizeof(bSigInfo));
71 iSigInfo->rawsig = cp;
73 RSA_MD2(Data, DataLen, hash);
75 status = gdss_rverify(Signature, hash, iSigInfo->pname,
76 iSigInfo->pinst, iSigInfo->prealm,
77 &gdss_pubkey, &iSigInfo->timestamp, iSigInfo->rawsig);
79 if (status) return (status);
80 return (GDSS_SUCCESS);
88 if (status) retval = 512; /* No provision for errors, so default value */
89 retval = sizeof(SigInfo) + (gdss_pubkey.nl)*4 + GDSS_PAD + 5;
93 static int pfetchkey()
96 unsigned char buffer[512];
98 if (gdss_have_key) return (0);
99 keyf = fopen("/etc/athena/gdss_public_key", "r");
101 keyf = fopen("/afs/net.mit.edu/system/config/gdss_public_key", "r");
102 if (keyf == NULL) return (GDSS_E_NOPUBKEY);
104 fread(buffer, 1, 512, keyf);
106 DecodePublic(buffer, &gdss_pubkey);
108 return (GDSS_SUCCESS);
111 GDSS_Recompose(aSigInfo, signature)
113 unsigned char *signature;
115 if (aSigInfo->rawsig == NULL) return (GDSS_E_BADINPUT);
116 return(gdss_recompose(aSigInfo, signature));
120 #include <sys/types.h>
121 #include <sys/socket.h>
122 #include <netinet/in.h>
124 #include <sys/time.h>
127 static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0 };
128 GDSS_Sign(Data, DataLen, Signature)
130 unsigned int DataLen;
131 unsigned char *Signature;
134 char lrealm[REALM_SZ];
138 unsigned char hash[16];
139 unsigned char dhash[16]; /* Second level hash */
140 int s; /* Socket to do i/o on */
144 unsigned char packet[2048];
146 unsigned char ipacket[2048];
149 struct sockaddr_in sin, lsin;
153 char *krb_get_phost();
155 memset(packet, 0, sizeof(packet)); /* Zeroize Memory */
156 memset(ipacket, 0, sizeof(ipacket));
157 krb_get_lrealm(lrealm, 1); /* Get our Kerberos realm */
159 RSA_MD2(Data, DataLen, hash);
160 RSA_MD2(hash, 16, dhash); /* For use of Kerberos */
161 memcpy(packet, hash, 16);
164 for (i = 0; i < 4; i++) /* High order 32 bits of dhash is the
165 Kerberos checksum, I wish we could do
166 better, but this is all kerberos allows
168 cksum = (cksum << 8) + dhash[i];
170 /* Use Hesiod to find service location of GDSS Server Here */
172 hostname = hes_resolve("gdss", "sloc");
173 if (hostname == NULL) return(-1); /* No hesiod available */
175 cp = krb_get_phost(*hostname);
176 if (cp == NULL) return (-1); /* Should use a better error code */
180 hp = gethostbyname(*hostname);
182 if(hp == NULL) return (-1); /* Could not find host, you lose */
184 memset(&sin, 0, sizeof(sin));
185 sin.sin_family = hp->h_addrtype;
186 memcpy(&sin.sin_addr, hp->h_addr, sizeof(hp->h_addr));
187 sin.sin_port = htons(7201); /* Should get this from services or Hesiod */
189 strcpy(linst, "gdss"); /* Grrr... krb_mk_req bashes its input
190 So we better copy it first! */
191 status = krb_mk_req(&authent, linst, sinst, lrealm, cksum);
192 if (status != KSUCCESS) return (GDSS_E_KRBFAIL);
193 packet[0] = 0; /* Version 0 of protocol */
194 memcpy(&packet[1], hash, 16);
195 memcpy(&packet[17], &authent, sizeof(authent));
196 plen = sizeof(authent) + 16 + 1; /* KTEXT_ST plus the hash + version */
198 s = -1; /* "NULL" Value for socket */
200 s = socket(AF_INET, SOCK_DGRAM, 0);
202 status = GDSS_E_NOSOCKET;
205 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
206 status = GDSS_E_NOCONNECT;
210 status = GDSS_E_TIMEDOUT;
212 if(send(s, packet, plen, 0) < 0) break;
215 if ((select(s+1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1)
216 || !FD_ISSET(s, &readfds)) {
220 if((iplen = recv(s, (char *)ipacket, 2048, 0)) < 0) break;
221 status = GDSS_SUCCESS;
227 if (status != GDSS_SUCCESS) return (status);
228 memcpy(Signature, ipacket, iplen);
229 return (GDSS_SUCCESS);