1*1131Smax.romanov@nginx.com 2*1131Smax.romanov@nginx.com /* 3*1131Smax.romanov@nginx.com * Copyright (C) NGINX, Inc. 4*1131Smax.romanov@nginx.com */ 5*1131Smax.romanov@nginx.com 6*1131Smax.romanov@nginx.com #include <nxt_main.h> 7*1131Smax.romanov@nginx.com #include <nxt_websocket.h> 8*1131Smax.romanov@nginx.com #include <nxt_sha1.h> 9*1131Smax.romanov@nginx.com 10*1131Smax.romanov@nginx.com 11*1131Smax.romanov@nginx.com static void 12*1131Smax.romanov@nginx.com nxt_websocket_base64_encode(u_char *d, const uint8_t *s, size_t len) 13*1131Smax.romanov@nginx.com { 14*1131Smax.romanov@nginx.com u_char c0, c1, c2; 15*1131Smax.romanov@nginx.com static u_char basis[] = 16*1131Smax.romanov@nginx.com "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 17*1131Smax.romanov@nginx.com 18*1131Smax.romanov@nginx.com while (len > 2) { 19*1131Smax.romanov@nginx.com c0 = s[0]; 20*1131Smax.romanov@nginx.com c1 = s[1]; 21*1131Smax.romanov@nginx.com c2 = s[2]; 22*1131Smax.romanov@nginx.com 23*1131Smax.romanov@nginx.com *d++ = basis[c0 >> 2]; 24*1131Smax.romanov@nginx.com *d++ = basis[((c0 & 0x03) << 4) | (c1 >> 4)]; 25*1131Smax.romanov@nginx.com *d++ = basis[((c1 & 0x0f) << 2) | (c2 >> 6)]; 26*1131Smax.romanov@nginx.com *d++ = basis[c2 & 0x3f]; 27*1131Smax.romanov@nginx.com 28*1131Smax.romanov@nginx.com s += 3; 29*1131Smax.romanov@nginx.com len -= 3; 30*1131Smax.romanov@nginx.com } 31*1131Smax.romanov@nginx.com 32*1131Smax.romanov@nginx.com if (len > 0) { 33*1131Smax.romanov@nginx.com c0 = s[0]; 34*1131Smax.romanov@nginx.com *d++ = basis[c0 >> 2]; 35*1131Smax.romanov@nginx.com 36*1131Smax.romanov@nginx.com if (len == 1) { 37*1131Smax.romanov@nginx.com *d++ = basis[(c0 & 0x03) << 4]; 38*1131Smax.romanov@nginx.com *d++ = '='; 39*1131Smax.romanov@nginx.com *d++ = '='; 40*1131Smax.romanov@nginx.com 41*1131Smax.romanov@nginx.com } else { 42*1131Smax.romanov@nginx.com c1 = s[1]; 43*1131Smax.romanov@nginx.com 44*1131Smax.romanov@nginx.com *d++ = basis[((c0 & 0x03) << 4) | (c1 >> 4)]; 45*1131Smax.romanov@nginx.com *d++ = basis[(c1 & 0x0f) << 2]; 46*1131Smax.romanov@nginx.com 47*1131Smax.romanov@nginx.com *d++ = '='; 48*1131Smax.romanov@nginx.com } 49*1131Smax.romanov@nginx.com } 50*1131Smax.romanov@nginx.com } 51*1131Smax.romanov@nginx.com 52*1131Smax.romanov@nginx.com 53*1131Smax.romanov@nginx.com void 54*1131Smax.romanov@nginx.com nxt_websocket_accept(u_char *accept, const void *key) 55*1131Smax.romanov@nginx.com { 56*1131Smax.romanov@nginx.com u_char bin_accept[20]; 57*1131Smax.romanov@nginx.com nxt_sha1_t ctx; 58*1131Smax.romanov@nginx.com static const char accept_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 59*1131Smax.romanov@nginx.com 60*1131Smax.romanov@nginx.com nxt_sha1_init(&ctx); 61*1131Smax.romanov@nginx.com nxt_sha1_update(&ctx, key, 24); 62*1131Smax.romanov@nginx.com nxt_sha1_update(&ctx, accept_guid, nxt_length(accept_guid)); 63*1131Smax.romanov@nginx.com nxt_sha1_final(bin_accept, &ctx); 64*1131Smax.romanov@nginx.com 65*1131Smax.romanov@nginx.com nxt_websocket_base64_encode(accept, bin_accept, sizeof(bin_accept)); 66*1131Smax.romanov@nginx.com } 67*1131Smax.romanov@nginx.com 68*1131Smax.romanov@nginx.com 69