Skip to content

Commit 0858f1b

Browse files
committed
Embed SHA1
1 parent afef1d4 commit 0858f1b

File tree

2 files changed

+268
-2
lines changed

2 files changed

+268
-2
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ cmake-build-debug
55
CMakeCache.txt
66
*.so
77
Makefile
8-
.idea/
8+
.idea/
9+
CMakeLists.txt

ngx_http_js_challenge.c

+266-1
Original file line numberDiff line numberDiff line change
@@ -235,22 +235,28 @@ int serve_challenge(ngx_http_request_t *r, const char *challenge, const char *ht
235235
return ngx_http_output_filter(r, &out);
236236
}
237237

238+
unsigned char *_sha1(const unsigned char *d, size_t n, unsigned char *md);
239+
238240
/**
239241
* @param out 40 bytes long string!
240242
*/
241243
void get_challenge_string(int32_t bucket, ngx_str_t addr, ngx_str_t secret, char *out) {
242244
char buf[4096];
243245
unsigned char md[SHA1_MD_LEN];
244246

245-
char * p = (char*)&bucket;
247+
char *p = (char *) &bucket;
246248
/*
247249
* Challenge= hex( SHA1( concat(bucket, addr, secret) ) )
248250
*/
249251
memcpy(buf, p, sizeof(bucket));
250252
memcpy((buf + sizeof(int32_t)), addr.data, addr.len);
251253
memcpy((buf + sizeof(int32_t) + addr.len), secret.data, secret.len);
252254

255+
#ifndef HEADER_SHA_H
256+
_sha1((unsigned char *) buf, (size_t) (sizeof(int32_t) + addr.len + secret.len), md);
257+
#else
253258
SHA1((unsigned char *) buf, (size_t) (sizeof(int32_t) + addr.len + secret.len), md);
259+
#endif
254260
buf2hex(md, SHA1_MD_LEN, out);
255261
}
256262

@@ -370,3 +376,262 @@ static ngx_int_t ngx_http_js_challenge(ngx_conf_t *cf) {
370376
return NGX_OK;
371377
}
372378

379+
/**
380+
* By Steve Reid <[email protected]>
381+
* 100% Public Domain
382+
*/
383+
#ifndef HEADER_SHA_H
384+
385+
#define SHA1HANDSOFF (1)
386+
387+
#include <stdint.h>
388+
389+
#include <stdio.h>
390+
#include <string.h>
391+
392+
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
393+
394+
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
395+
396+
#if defined (BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
397+
#define WORDS_BIGENDIAN 1
398+
#endif
399+
#ifdef _BIG_ENDIAN
400+
#define WORDS_BIGENDIAN 1
401+
#endif
402+
403+
404+
/* blk0() and blk() perform the initial expand. */
405+
/* I got the idea of expanding during the round function from SSLeay */
406+
/* FIXME: can we do this in an endian-proof way? */
407+
#ifdef WORDS_BIGENDIAN
408+
#define blk0(i) block->l[i]
409+
#else
410+
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xff00ff00) \
411+
|(rol(block->l[i],8)&0x00ff00ff))
412+
#endif
413+
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
414+
^block->l[(i+2)&15]^block->l[i&15],1))
415+
416+
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
417+
#define R0(v, w, x, y, z, i) \
418+
z+=((w&(x^y))^y)+blk0(i)+0x5a827999+rol(v,5);w=rol(w,30);
419+
#define R1(v, w, x, y, z, i) \
420+
z+=((w&(x^y))^y)+blk(i)+0x5a827999+rol(v,5);w=rol(w,30);
421+
#define R2(v, w, x, y, z, i) \
422+
z+=(w^x^y)+blk(i)+0x6ed9eba1+rol(v,5);w=rol(w,30);
423+
#define R3(v, w, x, y, z, i) \
424+
z+=(((w|x)&y)|(w&x))+blk(i)+0x8f1bbcdc+rol(v,5);w=rol(w,30);
425+
#define R4(v, w, x, y, z, i) \
426+
z+=(w^x^y)+blk(i)+0xca62c1d6+rol(v,5);w=rol(w,30);
427+
428+
429+
/* Hash a single 512-bit block. This is the core of the algorithm. */
430+
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]) {
431+
uint32_t a, b, c, d, e;
432+
typedef union {
433+
uint8_t c[64];
434+
uint32_t l[16];
435+
} CHAR64LONG16;
436+
CHAR64LONG16 *block;
437+
438+
#ifdef SHA1HANDSOFF
439+
CHAR64LONG16 workspace;
440+
block = &workspace;
441+
memcpy(block, buffer, 64);
442+
#else
443+
block = (CHAR64LONG16*)buffer;
444+
#endif
445+
446+
/* Copy context->state[] to working vars */
447+
a = state[0];
448+
b = state[1];
449+
c = state[2];
450+
d = state[3];
451+
e = state[4];
452+
453+
/* 4 rounds of 20 operations each. Loop unrolled. */
454+
R0(a, b, c, d, e, 0);
455+
R0(e, a, b, c, d, 1);
456+
R0(d, e, a, b, c, 2);
457+
R0(c, d, e, a, b, 3);
458+
R0(b, c, d, e, a, 4);
459+
R0(a, b, c, d, e, 5);
460+
R0(e, a, b, c, d, 6);
461+
R0(d, e, a, b, c, 7);
462+
R0(c, d, e, a, b, 8);
463+
R0(b, c, d, e, a, 9);
464+
R0(a, b, c, d, e, 10);
465+
R0(e, a, b, c, d, 11);
466+
R0(d, e, a, b, c, 12);
467+
R0(c, d, e, a, b, 13);
468+
R0(b, c, d, e, a, 14);
469+
R0(a, b, c, d, e, 15);
470+
R1(e, a, b, c, d, 16);
471+
R1(d, e, a, b, c, 17);
472+
R1(c, d, e, a, b, 18);
473+
R1(b, c, d, e, a, 19);
474+
R2(a, b, c, d, e, 20);
475+
R2(e, a, b, c, d, 21);
476+
R2(d, e, a, b, c, 22);
477+
R2(c, d, e, a, b, 23);
478+
R2(b, c, d, e, a, 24);
479+
R2(a, b, c, d, e, 25);
480+
R2(e, a, b, c, d, 26);
481+
R2(d, e, a, b, c, 27);
482+
R2(c, d, e, a, b, 28);
483+
R2(b, c, d, e, a, 29);
484+
R2(a, b, c, d, e, 30);
485+
R2(e, a, b, c, d, 31);
486+
R2(d, e, a, b, c, 32);
487+
R2(c, d, e, a, b, 33);
488+
R2(b, c, d, e, a, 34);
489+
R2(a, b, c, d, e, 35);
490+
R2(e, a, b, c, d, 36);
491+
R2(d, e, a, b, c, 37);
492+
R2(c, d, e, a, b, 38);
493+
R2(b, c, d, e, a, 39);
494+
R3(a, b, c, d, e, 40);
495+
R3(e, a, b, c, d, 41);
496+
R3(d, e, a, b, c, 42);
497+
R3(c, d, e, a, b, 43);
498+
R3(b, c, d, e, a, 44);
499+
R3(a, b, c, d, e, 45);
500+
R3(e, a, b, c, d, 46);
501+
R3(d, e, a, b, c, 47);
502+
R3(c, d, e, a, b, 48);
503+
R3(b, c, d, e, a, 49);
504+
R3(a, b, c, d, e, 50);
505+
R3(e, a, b, c, d, 51);
506+
R3(d, e, a, b, c, 52);
507+
R3(c, d, e, a, b, 53);
508+
R3(b, c, d, e, a, 54);
509+
R3(a, b, c, d, e, 55);
510+
R3(e, a, b, c, d, 56);
511+
R3(d, e, a, b, c, 57);
512+
R3(c, d, e, a, b, 58);
513+
R3(b, c, d, e, a, 59);
514+
R4(a, b, c, d, e, 60);
515+
R4(e, a, b, c, d, 61);
516+
R4(d, e, a, b, c, 62);
517+
R4(c, d, e, a, b, 63);
518+
R4(b, c, d, e, a, 64);
519+
R4(a, b, c, d, e, 65);
520+
R4(e, a, b, c, d, 66);
521+
R4(d, e, a, b, c, 67);
522+
R4(c, d, e, a, b, 68);
523+
R4(b, c, d, e, a, 69);
524+
R4(a, b, c, d, e, 70);
525+
R4(e, a, b, c, d, 71);
526+
R4(d, e, a, b, c, 72);
527+
R4(c, d, e, a, b, 73);
528+
R4(b, c, d, e, a, 74);
529+
R4(a, b, c, d, e, 75);
530+
R4(e, a, b, c, d, 76);
531+
R4(d, e, a, b, c, 77);
532+
R4(c, d, e, a, b, 78);
533+
R4(b, c, d, e, a, 79);
534+
535+
/* Add the working vars back into context.state[] */
536+
state[0] += a;
537+
state[1] += b;
538+
state[2] += c;
539+
state[3] += d;
540+
state[4] += e;
541+
542+
/* Wipe variables */
543+
a = b = c = d = e = 0;
544+
}
545+
546+
/** SHA-1 Context */
547+
typedef struct {
548+
uint32_t state[5];
549+
/**< Context state */
550+
uint32_t count[2];
551+
/**< Counter */
552+
uint8_t buffer[64]; /**< SHA-1 buffer */
553+
} SHA1_CTX;
554+
555+
/** SHA-1 Digest size in bytes */
556+
#define SHA1_DIGEST_SIZE 20
557+
558+
void SHA1_Init(SHA1_CTX *context);
559+
560+
void SHA1_Update(SHA1_CTX *context, const void *p, size_t len);
561+
562+
void SHA1_Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX *context);
563+
564+
/**
565+
* Run your data through this
566+
*
567+
* @param context SHA1-Context
568+
* @param p Buffer to run SHA1 on
569+
* @param len Number of bytes
570+
*/
571+
void SHA1_Update(SHA1_CTX *context, const void *p, size_t len) {
572+
const uint8_t *data = p;
573+
size_t i, j;
574+
575+
j = (context->count[0] >> 3) & 63;
576+
if ((context->count[0] += (uint32_t) (len << 3)) < (len << 3)) {
577+
context->count[1]++;
578+
}
579+
context->count[1] += (uint32_t) (len >> 29);
580+
if ((j + len) > 63) {
581+
memcpy(&context->buffer[j], data, (i = 64 - j));
582+
SHA1_Transform(context->state, context->buffer);
583+
for (; i + 63 < len; i += 64) {
584+
SHA1_Transform(context->state, data + i);
585+
}
586+
j = 0;
587+
} else i = 0;
588+
memcpy(&context->buffer[j], &data[i], len - i);
589+
}
590+
591+
592+
/**
593+
* Add padding and return the message digest
594+
*
595+
* @param digest Generated message digest
596+
* @param context SHA1-Context
597+
*/
598+
void SHA1_Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX *context) {
599+
uint32_t i;
600+
uint8_t finalcount[8];
601+
602+
for (i = 0; i < 8; i++) {
603+
finalcount[i] = (uint8_t) ((context->count[(i >= 4 ? 0 : 1)]
604+
>> ((3 - (i & 3)) * 8)) & 255);
605+
}
606+
SHA1_Update(context, (uint8_t *) "\200", 1);
607+
while ((context->count[0] & 504) != 448) {
608+
SHA1_Update(context, (uint8_t *) "\0", 1);
609+
}
610+
SHA1_Update(context, finalcount, 8); /* Should cause SHA1_Transform */
611+
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
612+
digest[i] = (uint8_t)
613+
((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
614+
}
615+
616+
/* Wipe variables */
617+
i = 0;
618+
memset(context->buffer, 0, 64);
619+
memset(context->state, 0, 20);
620+
memset(context->count, 0, 8);
621+
memset(finalcount, 0, 8); /* SWR */
622+
623+
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
624+
SHA1_Transform(context->state, context->buffer);
625+
#endif
626+
}
627+
628+
unsigned char *_sha1(const unsigned char *d, size_t n, unsigned char *md) {
629+
SHA1_CTX c;
630+
SHA1_Init(&c);
631+
SHA1_Update(&c, d, n);
632+
SHA1_Final(md, &c);
633+
return md;
634+
}
635+
636+
#endif
637+

0 commit comments

Comments
 (0)