summaryrefslogtreecommitdiff
path: root/src/sp_crypt.c
diff options
context:
space:
mode:
authorkkadosh2018-05-29 19:34:16 +0000
committerjvoisin2018-05-29 19:34:16 +0000
commit7832438b7abedf567ce6376f99949f419abcdff1 (patch)
tree560e43918d1dc36ce4cf760a5b27aed0c563bc1c /src/sp_crypt.c
parent9eebe8c67e03e3041d454ea28e93996f7a67740b (diff)
Support session encryption
Implement session encryption.
Diffstat (limited to 'src/sp_crypt.c')
-rw-r--r--src/sp_crypt.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/src/sp_crypt.c b/src/sp_crypt.c
index 0c40f1f..55ae37b 100644
--- a/src/sp_crypt.c
+++ b/src/sp_crypt.c
@@ -4,9 +4,7 @@
4 4
5ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus) 5ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus)
6 6
7static zend_long nonce_d = 0; 7void generate_key(unsigned char *key) {
8
9static void generate_key(unsigned char *key) {
10 PHP_SHA256_CTX ctx; 8 PHP_SHA256_CTX ctx;
11 const char *user_agent = getenv("HTTP_USER_AGENT"); 9 const char *user_agent = getenv("HTTP_USER_AGENT");
12 const char *env_var = 10 const char *env_var =
@@ -50,14 +48,13 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) {
50 debase64 = php_base64_decode((unsigned char *)(Z_STRVAL_P(pDest)), 48 debase64 = php_base64_decode((unsigned char *)(Z_STRVAL_P(pDest)),
51 Z_STRLEN_P(pDest)); 49 Z_STRLEN_P(pDest));
52 50
53 if (ZSTR_LEN(debase64) < 51 if (ZSTR_LEN(debase64) < crypto_secretbox_NONCEBYTES) {
54 crypto_secretbox_NONCEBYTES + crypto_secretbox_ZEROBYTES) {
55 if (true == simulation) { 52 if (true == simulation) {
56 sp_log_msg( 53 sp_log_msg(
57 "cookie_encryption", SP_LOG_SIMULATION, 54 "cookie_encryption", SP_LOG_SIMULATION,
58 "Buffer underflow tentative detected in cookie encryption handling " 55 "Buffer underflow tentative detected in cookie encryption handling "
59 "for %s. Using the cookie 'as it' instead of decrypting it.", 56 "for %s. Using the cookie 'as it' instead of decrypting it.",
60 ZSTR_VAL(hash_key->key)); 57 hash_key ? ZSTR_VAL(hash_key->key) : "the session");
61 return ZEND_HASH_APPLY_KEEP; 58 return ZEND_HASH_APPLY_KEEP;
62 } else { 59 } else {
63 sp_log_msg( 60 sp_log_msg(
@@ -67,9 +64,26 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) {
67 } 64 }
68 } 65 }
69 66
67
68 if (ZSTR_LEN(debase64) + (size_t)crypto_secretbox_ZEROBYTES < ZSTR_LEN(debase64)) {
69 if (true == simulation) {
70 sp_log_msg(
71 "cookie_encryption", SP_LOG_SIMULATION,
72 "Integer overflow tentative detected in cookie encryption handling "
73 "for %s. Using the cookie 'as it' instead of decrypting it.",
74 hash_key ? ZSTR_VAL(hash_key->key) : "the session");
75 return ZEND_HASH_APPLY_KEEP;
76 } else {
77 sp_log_msg(
78 "cookie_encryption", SP_LOG_DROP,
79 "Integer overflow tentative detected in cookie encryption handling.");
80 return ZEND_HASH_APPLY_REMOVE;
81 }
82 }
83
70 generate_key(key); 84 generate_key(key);
71 85
72 decrypted = ecalloc(ZSTR_LEN(debase64), 1); 86 decrypted = ecalloc(ZSTR_LEN(debase64) + crypto_secretbox_ZEROBYTES, 1);
73 87
74 ret = crypto_secretbox_open( 88 ret = crypto_secretbox_open(
75 decrypted, 89 decrypted,
@@ -83,12 +97,12 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) {
83 "cookie_encryption", SP_LOG_SIMULATION, 97 "cookie_encryption", SP_LOG_SIMULATION,
84 "Something went wrong with the decryption of %s. Using the cookie " 98 "Something went wrong with the decryption of %s. Using the cookie "
85 "'as it' instead of decrypting it", 99 "'as it' instead of decrypting it",
86 ZSTR_VAL(hash_key->key)); 100 hash_key ? ZSTR_VAL(hash_key->key) : "the session");
87 return ZEND_HASH_APPLY_KEEP; 101 return ZEND_HASH_APPLY_KEEP;
88 } else { 102 } else {
89 sp_log_msg("cookie_encryption", SP_LOG_DROP, 103 sp_log_msg("cookie_encryption", SP_LOG_DROP,
90 "Something went wrong with the decryption of %s.", 104 "Something went wrong with the decryption of %s.",
91 ZSTR_VAL(hash_key->key)); 105 hash_key ? ZSTR_VAL(hash_key->key) : "the session");
92 return ZEND_HASH_APPLY_REMOVE; 106 return ZEND_HASH_APPLY_REMOVE;
93 } 107 }
94 } 108 }
@@ -100,8 +114,14 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) {
100 return ZEND_HASH_APPLY_KEEP; 114 return ZEND_HASH_APPLY_KEEP;
101} 115}
102 116
117/*
118** This function will return the `data` of length `data_len` encrypted in the
119** form `base64(nonce | encrypted_data)` (with `|` being the concatenation
120** operation).
121*/
103zend_string *encrypt_zval(char *data, unsigned long long data_len) { 122zend_string *encrypt_zval(char *data, unsigned long long data_len) {
104 const size_t encrypted_msg_len = crypto_secretbox_ZEROBYTES + data_len + 1; 123 const size_t encrypted_msg_len = crypto_secretbox_ZEROBYTES + data_len + 1;
124 // FIXME : We know that this len is too long
105 const size_t emsg_and_nonce_len = 125 const size_t emsg_and_nonce_len =
106 encrypted_msg_len + crypto_secretbox_NONCEBYTES; 126 encrypted_msg_len + crypto_secretbox_NONCEBYTES;
107 127
@@ -112,25 +132,21 @@ zend_string *encrypt_zval(char *data, unsigned long long data_len) {
112 132
113 generate_key(key); 133 generate_key(key);
114 134
135 // Put random bytes in the nonce
136 php_random_bytes(nonce, sizeof(nonce), 0);
137
115 /* tweetnacl's API requires the message to be padded with 138 /* tweetnacl's API requires the message to be padded with
116 crypto_secretbox_ZEROBYTES zeroes. */ 139 crypto_secretbox_ZEROBYTES zeroes. */
117 memcpy(data_to_encrypt + crypto_secretbox_ZEROBYTES, data, data_len); 140 memcpy(data_to_encrypt + crypto_secretbox_ZEROBYTES, data, data_len);
118 141
119 assert(sizeof(zend_long) <= crypto_secretbox_NONCEBYTES); 142 assert(sizeof(zend_long) <= crypto_secretbox_NONCEBYTES);
120 143
121 if (0 == nonce_d) {
122 /* A zend_long should be enough to avoid collisions */
123 if (php_random_int_throw(0, ZEND_LONG_MAX, &nonce_d) == FAILURE) {
124 return NULL; // LCOV_EXCL_LINE
125 }
126 }
127 nonce_d++;
128 sscanf((char *)nonce, "%ld", &nonce_d);
129
130 memcpy(encrypted_data, nonce, crypto_secretbox_NONCEBYTES); 144 memcpy(encrypted_data, nonce, crypto_secretbox_NONCEBYTES);
145
131 crypto_secretbox(encrypted_data + crypto_secretbox_NONCEBYTES, 146 crypto_secretbox(encrypted_data + crypto_secretbox_NONCEBYTES,
132 data_to_encrypt, encrypted_msg_len, nonce, key); 147 data_to_encrypt, encrypted_msg_len, nonce, key);
133 148
134 zend_string *z = php_base64_encode(encrypted_data, emsg_and_nonce_len); 149 zend_string *z = php_base64_encode(encrypted_data, emsg_and_nonce_len);
150
135 return z; 151 return z;
136} \ No newline at end of file 152} \ No newline at end of file