]> andersk Git - moira.git/blame - util/gdss/lib/crypto/algorithm/bigsignverify.c
Remove incorrect krb_get_lrealm() prototype.
[moira.git] / util / gdss / lib / crypto / algorithm / bigsignverify.c
CommitLineData
0095f096 1/*
2 * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
3 * ALL RIGHTS RESERVED
4 *
5 * "Digital Equipment Corporation authorizes the reproduction,
6 * distribution and modification of this software subject to the following
7 * restrictions:
8 *
9 * 1. Any partial or whole copy of this software, or any modification
10 * thereof, must include this copyright notice in its entirety.
11 *
12 * 2. This software is supplied "as is" with no warranty of any kind,
13 * expressed or implied, for any purpose, including any warranty of fitness
14 * or merchantibility. DIGITAL assumes no responsibility for the use or
15 * reliability of this software, nor promises to provide any form of
16 * support for it on any basis.
17 *
18 * 3. Distribution of this software is authorized only if no profit or
19 * remuneration of any kind is received in exchange for such distribution.
20 *
21 * 4. This software produces public key authentication certificates
22 * bearing an expiration date established by DIGITAL and RSA Data
23 * Security, Inc. It may cease to generate certificates after the expiration
24 * date. Any modification of this software that changes or defeats
25 * the expiration date or its effect is unauthorized.
26 *
27 * 5. Software that will renew or extend the expiration date of
28 * authentication certificates produced by this software may be obtained
29 * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
30 * 94065, (415)595-8782, or from DIGITAL"
31 *
32 */
33
34#include <stdio.h>
35#include <sys/types.h>
36#include <time.h>
37#include <syslog.h>
38#include "bigsignverify.h"
39
40#ifdef DEBUG
41#undef DEBUG
42#endif
43
44/* in-line crypto routines here */
45
46#include "RSAcrypto.h"
47#include "DEScrypto.h"
48
49#define CLOCK_SKEW 5*60
50
51#ifdef mips
52#undef BnnSetToZero
53#endif
54
55/*
56 * Global
57 */
58
59static BigNumDigit buffer1[2*DigitLim], buffer2[2*DigitLim];
60
61/*
62 * RSASign takes a key in local format and a counted character string and
63 * writes a signature in "BER INTEGER" encoded format into the supplied buffer.
64 * The length in bytes is also written.
65 *
66 */
67
68int RSASign (toBeSigned, datalen, key, signature, siglen)
69RSAKeyStorage *key;
70unsigned char *toBeSigned;
71unsigned char *signature; /* output assumed large enough to hold modulus */
72int datalen, *siglen; /* in bytes */
73{
74 char *temp = (char *)buffer2;
75 int i, nl=key->nl, pl=key->pl, ql=key->ql;
76 BigNum signed_digest = buffer1, p = key->p, q = key->q;
77
78 if ((pl==0)||(ql==0)) return(0); /* not a private key */
79 RSA_MD2(toBeSigned, datalen, temp); /* hash to temp */
80 BnnSetToZero(signed_digest,nl);
81 for (i=0;i<16;i++) /* copy in right order */
82 signed_digest[i/sizeof(BigNumDigit)]|=
83 ((0x0ff&temp[15-i])<<((i%sizeof(BigNumDigit))*8));
84 signed_digest[4] |= 0x00000410;
85 rsadecrypt_1(signed_digest, signed_digest, key);
86 *siglen = NumEncodeValueOctets(signed_digest, nl);
87 if(EncodeBigIntegerValue(signature, signed_digest, nl)) return(TRUE);
88 else return(FALSE);
89}
90
91/*
92 * RSAVerify takes an encoded signature, allegedly signed data and key
93 * and yields a boolean (TRUE/FALSE).
94 */
95
96int RSAVerify (allegedSigned, datalen, key, signature, siglen)
97RSAKeyStorage *key;
98char *allegedSigned, *signature;
99int datalen, siglen;
100{
101 char *temp=(char *)buffer2;
102 BigNum md = buffer1, buffer = buffer2, n = key->n;
103 int i, bl, nl=key->nl;
104
105 if ((bl=(siglen+sizeof(BigNumDigit)-1)/sizeof(BigNumDigit)) > nl) {
106#ifdef DEBUG
107printf("\nRSAVerify: signature has more BigNumDigits than the modulus\n");
108#endif
109 return(FALSE);
110 }
111
112 BnnSetToZero(md,nl);
113 RSA_MD2(allegedSigned, datalen, temp);
114 for (i=0;i<16;i++) /* copy in right order */
115 md[i/sizeof(BigNumDigit)]|=((0x0ff&temp[15-i])<<((i%sizeof(BigNumDigit))*8));
116
117 BnnSetToZero(buffer,nl);
118 DecodeBigInteger(signature, buffer, siglen);
119 if (BnnCompare(n, nl, buffer, bl)!=1) {
120#ifdef DEBUG
121printf("\nRSAVerify: signature is larger BigNum value than modulus\n");
122#endif
123 return(FALSE);
124 }
125
126 rsaencrypt_1(buffer, buffer, key);
127#ifdef DEBUG
128printf("RSAVerify: computed md:\n");
129dumphex(md,nl*8);
130printf("RSAVerify: recovered md:\n");
131dumphex(buffer,nl*8);
132#endif
133 buffer[4] &= 0xffff0000;
134 if (BnnCompare(md,nl,buffer,nl)==0) return (TRUE);
135#ifdef DEBUG
136printf("\nRSAVerify: signature verification failed.\n");
137#endif
138 return(FALSE);
139
140}
141
142\f
143/*
144 * The initialization routine generates a DES key and encrypts it under
145 * the public key of the intended verifier principal.
146 *
147 * A word about byte ordering. The "least significant byte" of a BigNum
148 * is the byte that has the least significant bit in it. The "most
149 * significant byte" has the most significant bit in it.
150 *
151 */
152#include "endian.h"
153#define RandomOffset (sizeof(DESblock)+2*sizeof(time_t))
154#define BYTE_IN_BIGNUM(x) (SPHINX_ENDIAN?(sizeof(BigNumDigit)-(x%sizeof(BigNumDigit)-1)):x)
155
156int InitAuthenticationKey (verifier, delegation, new_key, encrypted_key,
157 encrypted_key_len, when_expires)
158RSAKeyStorage *verifier, *delegation;
159DESblock *new_key;
160unsigned char *encrypted_key;
161int *encrypted_key_len;
162time_t when_expires;
163{
164 time_t when_signed;
165 BigNum vn=verifier->n, p = buffer1, temp = buffer1;
166 int i, leading_zero_bytes, vnl=verifier->nl, tl;
167 RNGState rng;
168
169 /*
170 * This is all we need the delegation key for.
171 */
172 read_rng_state(&rng);
173 if(((rng.count)==0)&&delegation) initialize_rng_state(delegation->p,16);
174
175 /*
176 * Fill temporary storage with a random number.
177 */
178 BnnSetToZero(temp,vnl+1);
179 tl = BnnNumDigits(vn,vnl);
180 random_BigNum(temp,tl);
181
182 /*
183 * There must always be one more significant byte in the modulus than
184 * the one that has the "64" in the encrypted key.
185 */
186#ifdef DEBUG
187printf("\nleading zero bits: %d, vn[tl-1]=%08x\n",
188 BnnNumLeadingZeroBitsInDigit(vn[tl-1]), vn[tl-1]);
189#endif
190 leading_zero_bytes=BnnNumLeadingZeroBitsInDigit(BnnGetDigit(vn+tl-1))/8;
191 if (leading_zero_bytes == (sizeof(BigNumDigit)-1)) {
192 /*
193 * There is only one significant byte in the most significant BigNumDigit,
194 * so zero out top digit and put "64" into the most significant byte of
195 * the next-to-top digit
196 */
197 temp[tl-1] = 0;
198 temp[tl-2] &= ~(0x00ff << 8*leading_zero_bytes);
199 temp[tl-2] |= 64 << 8*leading_zero_bytes ;
200 }
201 else {
202 /*
203 * Zero out bytes with significant stuff in them, and put "64"
204 * in the next-most-significant byte.
205 */
206 for(i=0;i<=leading_zero_bytes+1;i++)
207 temp[tl-1] &= ~(0x00ff << (8*(sizeof(BigNumDigit)-1-i)));
208 temp[tl-1] |= 64<<((sizeof(BigNumDigit)-2-leading_zero_bytes)*8);
209 }
210#ifdef DEBUG
211printf("\nleading_zero_bytes=%d\n",leading_zero_bytes);
212printf("\ntl=%d, vnl=%d, temp[tl-1]=%08x, temp[tl-2]=%08x\n", tl, vnl, temp[tl-1], temp[tl-2]);
213#endif
214
215 BnnSetToZero(temp, (RandomOffset+4)/sizeof(BigNumDigit));
216 /*
217 * Generate 8 bytes of DES key, copy into buffer in right order
218 */
219 random_bytes(temp, sizeof(DESblock));
220 for (i=0;i<sizeof(DESblock);i++) new_key->bytes[sizeof(DESblock)-i-1] =
221 (temp[i/sizeof(BigNumDigit)]>>((i%sizeof(BigNumDigit)*8)));
222
223 /*
224 * Assume sizeof(time_t) == sizeof(BigNumDigit).
225 * Everyone has to swap these bytes, I guess.
226 */
227 time(&when_signed);
228 p = &temp[sizeof(DESblock)/sizeof(BigNumDigit)];
229 p[0]=when_signed;
230 p[1]=when_expires;
231/*
232 for(i=0;i<sizeof(time_t);i++) {
233 p[0] |= ((when_signed>>(i*8))&(BigNumDigit)0xff)<<((sizeof(time_t)-1-i)*8);
234 p[1] |= ((when_expires>>(i*8))&(BigNumDigit)0xff)<<((sizeof(time_t)-1-i)*8);
235 }
236*/
237#ifdef DEBUG
238printf("\nBlock to encrypt: (low to high order bytes) \n");
239dumphex(temp,tl*sizeof(BigNumDigit));
240printf("\nModulus:\n");
241dumphex(vn,vnl*sizeof(BigNumDigit));
242#endif
243 rsaencrypt_1(temp,temp,verifier);
244 *encrypted_key_len = NumEncodeValueOctets(temp,tl);
245 if (EncodeBigIntegerValue(encrypted_key,temp,tl)) return(TRUE);
246 else return(FALSE);
247}
248
249/*
250 * The accept routine takes in encoded elements and yields the transferred
251 * DES key along with an expiration date.
252 *
253 */
254int AcceptAuthenticationKey (verifier, new_key, encrypted_key,
255 encrypted_key_len, when_expires)
256RSAKeyStorage *verifier;
257DESblock *new_key;
258unsigned char *encrypted_key;
259int encrypted_key_len;
260time_t *when_expires;
261{
262 time_t now, when_signed, when_expires_temp ;
263 int i, tl, vnl=verifier->nl, leading_zero_bytes;
264 BigNum vn=verifier->n, p = buffer1, temp = buffer1;
265 char *ptr;
266
267 BnnSetToZero(temp,vnl+1);
268 if ((tl=(encrypted_key_len+sizeof(BigNumDigit)-1)/sizeof(BigNumDigit)) > vnl) {
269#ifdef DEBUG
270printf("\nAcceptAuthenticationKey: Signature has more BigNumDigits than modulus.\n");
271#endif
272syslog(LOG_INFO, "AAK : Signature has more BigNumDigits than modulus");
273 goto error;
274 }
275
276 DecodeBigInteger(encrypted_key,temp,encrypted_key_len);
277 if (BnnCompare(vn,vnl,temp,tl) != 1) {
278#ifdef DEBUG
279printf("\nAcceptAuthenticationKey: Signature is larger than modulus.\n");
280#endif
281syslog(LOG_INFO, "AAK : Signature is larger than modulus");
282 goto error;
283 }
284
285 rsadecrypt_1(temp,temp,verifier);
286#ifdef DEBUG
287printf("\nAcceptAuthenticationKey: Decrypted key:\n");
288dumphex(temp,(vnl+1)*sizeof(BigNumDigit));
289fflush(stdout);
290#endif
291 /*
292 * Check for a "64" in the right place.
293 */
294 tl = BnnNumDigits(vn,vnl);
295 leading_zero_bytes=BnnNumLeadingZeroBitsInDigit(BnnGetDigit(vn+tl-1))/8;
296 if (leading_zero_bytes == sizeof(BigNumDigit)-1) {
297 if ((temp[tl-1] != 0) ||
298 (((temp[tl-2]>>(8*leading_zero_bytes))&0x0ff) != 64)) {
299#ifdef DEBUG
300printf("\nTop digit not zero, or 64 byte test failed.\n");
301#endif
302syslog(LOG_INFO, "AAK : Top digit not zero, or 64 byte test failed");
303 goto error ;
304 }
305 }
306 else { for(i=0;i<leading_zero_bytes;i++)
307 if(((temp[tl-1]>>((sizeof(BigNumDigit)-leading_zero_bytes-1+i)*8))&0x0ff)
308 != 0) {
309#ifdef DEBUG
310printf("\nTop byte zero test failed.\n");
311#endif
312syslog(LOG_INFO, "AAK : Top byte zero test failed");
313 goto error ;
314 }
315 if (((temp[tl-1]>>((sizeof(BigNumDigit)-2-leading_zero_bytes)*8))&0xff)
316 != 64){
317#ifdef DEBUG
318printf("\nTop byte 64 test failed.\n");
319#endif
320syslog(LOG_INFO, "AAK : Top byte 64 test failed");
321 goto error ;
322 }
323 }
324
325 ptr = (char *) &temp[RandomOffset/sizeof(BigNumDigit)];
326 for (i=0;i<4;i++) if (*ptr++ !=0) {
327#ifdef DEBUG
328printf("\nAcceptAuthenticationKey: Zero mid-buffer error.\n");
329#endif
330syslog(LOG_INFO, "AAK : Zero mid-buffer error");
331 goto error;
332 }
333
334 when_signed=when_expires_temp=0;
335
336 p = &temp[sizeof(DESblock)/sizeof(BigNumDigit)];
337 when_signed = p[0];
338 when_expires_temp = p[1];
339/*
340 for(i=0;i<sizeof(time_t);i++) {
341 when_signed |= ((p[0]>>(i*8))&(BigNumDigit)0x0ff)<<((sizeof(time_t)-1-i)*8);
342 when_expires_temp |= ((p[1]>>(i*8))&(BigNumDigit)0x0ff)<<((sizeof(time_t)-1-i)*8);
343 }
344*/
345 time(&now);
346#ifdef DEBUG
347printf("\n Signed: %s", ctime(&when_signed));
348printf("\n Expires: %s\n", ctime(&when_expires_temp));
349#endif
350
351 if((when_signed > now + CLOCK_SKEW) || (when_expires_temp < now - CLOCK_SKEW)) {
352#ifdef DEBUG
353printf("\nAcceptAuthenticationKey: Key Has Expired.\n");
354#endif
355syslog(LOG_INFO, "AAK : signed on (%d) %s", when_signed, ctime(&when_signed));
356syslog(LOG_INFO, "AAK : expire on (%d) %s", when_expires_temp, ctime(&when_expires_temp));
357syslog(LOG_INFO, "AAK : key has expired - now is %d", now);
358 goto error;
359 }
360 *when_expires = when_expires_temp;
361
362 for (i=0;i<sizeof(DESblock);i++) new_key->bytes[sizeof(DESblock)-i-1] =
363 (temp[i/sizeof(BigNumDigit)]>>((i%sizeof(BigNumDigit)*8)));
364 return(TRUE);
365
366error:
367 return(FALSE);
368
369}
370
This page took 1.025714 seconds and 5 git commands to generate.