@@ -235,22 +235,28 @@ int serve_challenge(ngx_http_request_t *r, const char *challenge, const char *ht
235
235
return ngx_http_output_filter (r , & out );
236
236
}
237
237
238
+ unsigned char * _sha1 (const unsigned char * d , size_t n , unsigned char * md );
239
+
238
240
/**
239
241
* @param out 40 bytes long string!
240
242
*/
241
243
void get_challenge_string (int32_t bucket , ngx_str_t addr , ngx_str_t secret , char * out ) {
242
244
char buf [4096 ];
243
245
unsigned char md [SHA1_MD_LEN ];
244
246
245
- char * p = (char * ) & bucket ;
247
+ char * p = (char * ) & bucket ;
246
248
/*
247
249
* Challenge= hex( SHA1( concat(bucket, addr, secret) ) )
248
250
*/
249
251
memcpy (buf , p , sizeof (bucket ));
250
252
memcpy ((buf + sizeof (int32_t )), addr .data , addr .len );
251
253
memcpy ((buf + sizeof (int32_t ) + addr .len ), secret .data , secret .len );
252
254
255
+ #ifndef HEADER_SHA_H
256
+ _sha1 ((unsigned char * ) buf , (size_t ) (sizeof (int32_t ) + addr .len + secret .len ), md );
257
+ #else
253
258
SHA1 ((unsigned char * ) buf , (size_t ) (sizeof (int32_t ) + addr .len + secret .len ), md );
259
+ #endif
254
260
buf2hex (md , SHA1_MD_LEN , out );
255
261
}
256
262
@@ -370,3 +376,262 @@ static ngx_int_t ngx_http_js_challenge(ngx_conf_t *cf) {
370
376
return NGX_OK ;
371
377
}
372
378
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