summaryrefslogtreecommitdiff
path: root/src/sp_cookie_encryption.c
diff options
context:
space:
mode:
authorkkadosh2018-05-15 15:08:34 +0000
committerjvoisin2018-05-15 15:08:34 +0000
commite0c2ca8624ebbf1a2c6ff9cff3d1284236e327e2 (patch)
tree3ec1f2c77a1d0654d5a34654f1c4bb3a9eacaf86 /src/sp_cookie_encryption.c
parent41b8db89d5f50aadad91d2b0fd9861017b58bb16 (diff)
Refactor the encryption process to extract encrypt/decrypt functions (#176)
Refactor the encryption process to extract encrypt/decrypt functions
Diffstat (limited to 'src/sp_cookie_encryption.c')
-rw-r--r--src/sp_cookie_encryption.c123
1 files changed, 2 insertions, 121 deletions
diff --git a/src/sp_cookie_encryption.c b/src/sp_cookie_encryption.c
index 4ecb97d..9030112 100644
--- a/src/sp_cookie_encryption.c
+++ b/src/sp_cookie_encryption.c
@@ -4,42 +4,6 @@
4 4
5ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus) 5ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus)
6 6
7static zend_long nonce_d = 0;
8
9static inline void generate_key(unsigned char *key) {
10 PHP_SHA256_CTX ctx;
11 const char *user_agent = getenv("HTTP_USER_AGENT");
12 const char *env_var =
13 getenv(SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var);
14 const char *encryption_key =
15 SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key;
16
17 assert(32 == crypto_secretbox_KEYBYTES); // 32 is the size of a SHA256.
18 assert(encryption_key); // Encryption key can't be NULL
19
20 PHP_SHA256Init(&ctx);
21
22 if (user_agent) {
23 PHP_SHA256Update(&ctx, (unsigned char *)user_agent, strlen(user_agent));
24 }
25
26 if (env_var) {
27 PHP_SHA256Update(&ctx, (unsigned char *)env_var, strlen(env_var));
28 } else {
29 sp_log_err("cookie_encryption",
30 "The environment variable '%s'"
31 "is empty, cookies are weakly encrypted.",
32 SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var);
33 }
34
35 if (encryption_key) {
36 PHP_SHA256Update(&ctx, (const unsigned char *)encryption_key,
37 strlen(encryption_key));
38 }
39
40 PHP_SHA256Final((unsigned char *)key, &ctx);
41}
42
43static inline const sp_cookie *sp_lookup_cookie_config(const char *key) { 7static inline const sp_cookie *sp_lookup_cookie_config(const char *key) {
44 sp_list_node *it = SNUFFLEUPAGUS_G(config).config_cookie->cookies; 8 sp_list_node *it = SNUFFLEUPAGUS_G(config).config_cookie->cookies;
45 9
@@ -56,9 +20,6 @@ static inline const sp_cookie *sp_lookup_cookie_config(const char *key) {
56/* called at RINIT time with each cookie, eventually decrypt said cookie */ 20/* called at RINIT time with each cookie, eventually decrypt said cookie */
57int decrypt_cookie(zval *pDest, int num_args, va_list args, 21int decrypt_cookie(zval *pDest, int num_args, va_list args,
58 zend_hash_key *hash_key) { 22 zend_hash_key *hash_key) {
59 unsigned char key[crypto_secretbox_KEYBYTES] = {0};
60 zend_string *debase64;
61 unsigned char *decrypted;
62 const sp_cookie *cookie = sp_lookup_cookie_config(ZSTR_VAL(hash_key->key)); 23 const sp_cookie *cookie = sp_lookup_cookie_config(ZSTR_VAL(hash_key->key));
63 int ret = 0; 24 int ret = 0;
64 25
@@ -72,57 +33,7 @@ int decrypt_cookie(zval *pDest, int num_args, va_list args,
72 return ZEND_HASH_APPLY_KEEP; 33 return ZEND_HASH_APPLY_KEEP;
73 } 34 }
74 35
75 debase64 = php_base64_decode((unsigned char *)(Z_STRVAL_P(pDest)), 36 return decrypt_zval(pDest, cookie->simulation, hash_key);
76 Z_STRLEN_P(pDest));
77
78 if (ZSTR_LEN(debase64) <
79 crypto_secretbox_NONCEBYTES + crypto_secretbox_ZEROBYTES) {
80 if (true == cookie->simulation) {
81 sp_log_msg(
82 "cookie_encryption", SP_LOG_SIMULATION,
83 "Buffer underflow tentative detected in cookie encryption handling "
84 "for %s. Using the cookie 'as it' instead of decrypting it.",
85 ZSTR_VAL(hash_key->key));
86 return ZEND_HASH_APPLY_KEEP;
87 } else {
88 sp_log_msg(
89 "cookie_encryption", SP_LOG_DROP,
90 "Buffer underflow tentative detected in cookie encryption handling.");
91 return ZEND_HASH_APPLY_REMOVE;
92 }
93 }
94
95 generate_key(key);
96
97 decrypted = ecalloc(ZSTR_LEN(debase64), 1);
98
99 ret = crypto_secretbox_open(
100 decrypted,
101 (unsigned char *)(ZSTR_VAL(debase64) + crypto_secretbox_NONCEBYTES),
102 ZSTR_LEN(debase64) - crypto_secretbox_NONCEBYTES,
103 (unsigned char *)ZSTR_VAL(debase64), key);
104
105 if (-1 == ret) {
106 if (true == cookie->simulation) {
107 sp_log_msg(
108 "cookie_encryption", SP_LOG_SIMULATION,
109 "Something went wrong with the decryption of %s. Using the cookie "
110 "'as it' instead of decrypting it",
111 ZSTR_VAL(hash_key->key));
112 return ZEND_HASH_APPLY_KEEP;
113 } else {
114 sp_log_msg("cookie_encryption", SP_LOG_DROP,
115 "Something went wrong with the decryption of %s.",
116 ZSTR_VAL(hash_key->key));
117 return ZEND_HASH_APPLY_REMOVE;
118 }
119 }
120
121 ZVAL_STRINGL(pDest, (char *)(decrypted + crypto_secretbox_ZEROBYTES),
122 ZSTR_LEN(debase64) - crypto_secretbox_NONCEBYTES - 1 -
123 crypto_secretbox_ZEROBYTES);
124
125 return ZEND_HASH_APPLY_KEEP;
126} 37}
127 38
128/* 39/*
@@ -131,37 +42,7 @@ int decrypt_cookie(zval *pDest, int num_args, va_list args,
131** operation). 42** operation).
132*/ 43*/
133static zend_string *encrypt_data(char *data, unsigned long long data_len) { 44static zend_string *encrypt_data(char *data, unsigned long long data_len) {
134 const size_t encrypted_msg_len = crypto_secretbox_ZEROBYTES + data_len + 1; 45 zend_string *z = encrypt_zval(data, data_len);
135 const size_t emsg_and_nonce_len =
136 encrypted_msg_len + crypto_secretbox_NONCEBYTES;
137
138 unsigned char key[crypto_secretbox_KEYBYTES] = {0};
139 unsigned char nonce[crypto_secretbox_NONCEBYTES] = {0};
140 unsigned char *data_to_encrypt = ecalloc(encrypted_msg_len, 1);
141 unsigned char *encrypted_data = ecalloc(emsg_and_nonce_len, 1);
142
143 generate_key(key);
144
145 /* tweetnacl's API requires the message to be padded with
146 crypto_secretbox_ZEROBYTES zeroes. */
147 memcpy(data_to_encrypt + crypto_secretbox_ZEROBYTES, data, data_len);
148
149 assert(sizeof(zend_long) <= crypto_secretbox_NONCEBYTES);
150
151 if (0 == nonce_d) {
152 /* A zend_long should be enough to avoid collisions */
153 if (php_random_int_throw(0, ZEND_LONG_MAX, &nonce_d) == FAILURE) {
154 return NULL; // LCOV_EXCL_LINE
155 }
156 }
157 nonce_d++;
158 sscanf((char *)nonce, "%ld", &nonce_d);
159
160 memcpy(encrypted_data, nonce, crypto_secretbox_NONCEBYTES);
161 crypto_secretbox(encrypted_data + crypto_secretbox_NONCEBYTES,
162 data_to_encrypt, encrypted_msg_len, nonce, key);
163
164 zend_string *z = php_base64_encode(encrypted_data, emsg_and_nonce_len);
165 sp_log_debug("cookie_encryption", "Cookie value:%s:", z->val); 46 sp_log_debug("cookie_encryption", "Cookie value:%s:", z->val);
166 return z; 47 return z;
167} 48}