Overview
SHA1 Hash: | 5468ec7c5ed45e567e0cee6780a7c37daa274356 |
---|---|
Date: | 2009-03-26 15:32:43 |
User: | drh |
Edited Comment: | Incremental changes toward encrypting sync traffic. The changes are incomplete, but all legacy functionality appears to still works. |
Original Comment: | Incremental changes toward encrypting sync traffic. The changes are incomplete, but all legacy functionality appears to still works. |
Timelines: | ancestors | descendants | both | experimental |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- bgcolor=#ffc0d0 propagates to descendants added by [cd9c421267] on 2009-03-29 12:09:27
- branch=experimental propagates to descendants added by [cd9c421267] on 2009-03-29 12:09:27
- comment=Incremental changes toward encrypting sync traffic. The changes are incomplete, but all legacy functionality appears to still works. added by [cd9c421267] on 2009-03-29 12:09:27
- sym-experimental propagates to descendants added by [cd9c421267] on 2009-03-29 12:09:27
-
sym-trunkcancelled by [cd9c421267] on 2009-03-29 12:09:27
Changes
[hide diffs]Modified src/blob.c from [1998856256] to [4adbb9d2f8].
@@ -843,10 +843,122 @@ blob_reset(&b1); blob_reset(&b2); blob_reset(&b3); } printf("ok\n"); +} + +/* +** Do an RC4 encryption/decryption. +** +** The key is formed by concatenating zPassword and aNonce and taking +** the sha1 hash of the result. The first 1000 bytes of the rc4 bytestream +** are discarded. The next nIn bytes of the rc4 bytestream are XORed +** against aIn and the result is written into aOut. +*/ +static void rc4_coder( + const char *zPassword, /* The password */ + const char *aNonce, /* One-time nonce for this encryption */ + int nNonce, /* Number of bytes in the nonce */ + const char *aIn, /* Input text */ + int nIn, /* Number of bytes of input text */ + char *aOut /* Output text */ +){ + Blob key; + int k; + unsigned char i, j, t; + unsigned char s[256]; + unsigned char *pKey; + int nKey; + + blob_zero(&key); + blob_append(&key, zPassword, -1); + blob_append(&key, aNonce, nNonce); + sha1sum_blob(&key, &key); + pKey = (unsigned char*)key.aData; + nKey = key.nUsed; + + /* Key the RC4 codec */ + for(k=0; k<256; k++) s[k] = k; + for(i=j=0, k=0; k<256; k++, i++){ + j += pKey[i % nKey] + s[i]; + t = s[i]; + s[i] = s[j]; + s[j] = t; + } + blob_reset(&key); + + /* Skip the first 1000 bytes of output */ + i = j = 0; + for(k=0; k<1000; k++){ + i++; + j += s[i]; + t = s[i]; + s[i] = s[j]; + s[j] = t; + } + + /* Encode nIn bytes */ + for(k=0; k<nIn; k++){ + i++; + j += s[i]; + t = s[i]; + s[i] = s[j]; + s[j] = t; + aOut[k] = aIn[k] ^ s[(s[i] + s[j])&255]; + } +} + +/* +** Encrypt a blob using RC4. +** +** The key is constructed by taking the sha1 hash of the password +** and a random 20-byte nonce. This nonce becomes the first 20 bytes +** of the encrypted output. The first 1000 bytes of the RC4 byte stream +** are discarded. The input is XORed against the remaining RC4 byte stream +** to generate the rest of the output. +** +** Only that portion of pIn beginning at the current cursor location and +** extending to the end of the blob is encrypted. Any content of pIn +** prior to the current cursor position is ignored. +** +** Because of the prepended nonce, the output will be 20 bytes larger +** than the input. +** +** pOut should be initialized prior to invoking this routine. pOut might +** already contain other content. The encryption is appended to pOut. +*/ +void blob_encrypt(Blob *pIn, const char *zPassword, Blob *pOut){ + unsigned char aNonce[20]; + unsigned char *aIn; + int nIn; + unsigned char *aOut; + + sqlite3_randomness(sizeof(aNonce), aNonce); + aIn = (unsigned char*)pIn->aData; + aIn += pIn->iCursor; + nIn = pIn->nUsed - pIn->iCursor; + if( nIn<=0 ) return; + +} + +/* +** Decrypt a blob. +** +** This routine undoes the work of blob_encrypt. pIn should be a blob +** that was generated by blob_encrypt. Assuming the same password is +** used, the original unencrypted text will be written into pOut. +** +** Only that portion of pIn beginning at the current cursor location and +** extending to the end of the blob is decrypted. Any content of pIn +** prior to the current cursor position is ignored. +** +** pOut should be initialized prior to invoking this routine. pOut might +** already contain other content. The encryption is appended to pOut. +*/ +void blob_decrypt(Blob *pIn, const char *zPassword, Blob *pOut){ + /* TBD... */ } #ifdef __MINGW32__ /* ** Convert every \n character in the given blob into \r\n.
Modified src/http.c from [099ac83ebe] to [a7c94bef96].
@@ -279,25 +279,39 @@ http_close(); return 0; } /* -** Sign the content in pSend, compress it, and send it to the server -** via HTTP. Get a reply, uncompress the reply, and store the reply -** in pRecv. pRecv is assumed to be uninitialized when +** Sign the content in pSend, compress it (if compression is turned on), +** encrypt it (if security is turned on), and send it to the server +** via HTTP. Get a reply, decrypt and uncompress the reply, and store +** the reply in pRecv. pRecv is assumed to be uninitialized when ** this routine is called - this routine will initialize it. ** ** The server address is contain in the "g" global structure. The ** url_parse() routine should have been called prior to this routine ** in order to fill this structure appropriately. */ void http_exchange(Blob *pSend, Blob *pRecv){ - Blob login, nonce, sig, pw, payload, hdr; + Blob login; /* The "login" card at the beginning of the payload */ + Blob nonce; /* The password verificatin nonce on the login card */ + Blob sig; /* The signature on the login card */ + Blob pw; /* The user password prefixed by the nonce */ + Blob payload; /* The HTTP request payload */ + Blob hdr; /* The HTTP request header */ const char *zSep; int i; int cnt = 0; + /* Compute the login card. This card is of the form: + ** + ** login USERID NONCE SIGNATURE + ** + ** The NONCE is a unique string - never to be reused. In this case, + ** the nonce is the SHA1 hash of the rest of the payload. The SIGNATURE + ** is the SHA1 hash of the NONCE and the user password concatenated. + */ blob_zero(&nonce); blob_zero(&pw); sha1sum_blob(pSend, &nonce); blob_copy(&pw, &nonce); blob_zero(&login); @@ -324,17 +338,23 @@ blob_appendf(&login, "login %s %b %b\n", g.urlUser, &nonce, &sig); } blob_reset(&nonce); blob_reset(&pw); blob_reset(&sig); + + /* Construct the payload, which includes the login card. + */ if( g.fHttpTrace ){ payload = login; blob_append(&payload, blob_buffer(pSend), blob_size(pSend)); }else{ blob_compress2(&login, pSend, &payload); blob_reset(&login); } + + /* Construct the HTTP request header + */ blob_zero(&hdr); i = strlen(g.urlPath); if( i>0 && g.urlPath[i-1]=='/' ){ zSep = ""; }else{ @@ -369,18 +389,26 @@ fwrite(blob_buffer(&hdr), 1, blob_size(&hdr), out); fwrite(blob_buffer(&payload), 1, blob_size(&payload), out); fclose(out); } } + + /* Send the header and payload to the server. Get the reply. If + ** the first attempt is unsuccessful, do a second attempt. + */ for(cnt=0; cnt<2; cnt++){ if( http_send_recv(&hdr, &payload, pRecv) ) break; } if( cnt>=2 ){ fossil_fatal("connection to server failed"); } blob_reset(&hdr); blob_reset(&payload); + + /* Process the reply. pRecv contains only the payload of the + ** reply message, not the header. + */ if( g.fHttpTrace ){ printf("HTTP RECEIVE:\n%s\n=======================\n", blob_str(pRecv)); }else{ blob_uncompress(pRecv, pRecv); }