1 module msgtrans.ee2e.common; 2 3 import msgtrans.ee2e.crypto; 4 import msgtrans.ee2e.message.MsgDefine; 5 import hunt.logging; 6 import msgtrans.MessageBuffer; 7 import std..string; 8 import google.protobuf; 9 import std.array; 10 import core.stdc..string; 11 import std.base64; 12 13 class common { 14 15 static bool keyCalculate(ownkey_s ownkey, peerkey_s peerkey) 16 { 17 ubyte[CRYPTO_SALT_LEN] salt_xor; 18 if (!bytes_xor(ownkey.salt, CRYPTO_SALT_LEN, peerkey.salt, CRYPTO_SALT_LEN, salt_xor)) 19 { 20 logError("xor calculation error."); 21 return false; 22 } 23 24 /* Calculate the shared key using own public and private keys and the public key of the other party */ 25 ubyte[CRYPTO_ECDH_SHARED_KEY_LEN] shared_key; 26 if (!calc_ecdh_shared_key(ownkey.ec_pub_key, ownkey.ec_priv_key, peerkey.ec_pub_key, shared_key)) 27 { 28 logError("shared key calculation error."); 29 return false; 30 } 31 32 /* Using HKDF to calculate the final AES key */ 33 if (!generate_hkdf_bytes(shared_key, salt_xor, CRYPTO_KEY_INFO.representation, CRYPTO_KEY_INFO.length, peerkey.aes_key)) 34 { 35 logError("hkdf calculation error."); 36 return false; 37 } 38 39 logInfo("Calculated the final AES-KEY: %s",peerkey.aes_key); 40 //dash::hex_dump(peerkey.aes_key, CRYPTO_AES_KEY_LEN, std::cout); 41 42 return true; 43 } 44 45 static bool encrypt_plaintext(peerkey_s peerkey, ubyte[] str_plaintext, Ciphertext ciphertext) 46 { 47 ubyte[] str_ciphertext = new ubyte[str_plaintext.length]; 48 ubyte[] rand_iv = new ubyte[CRYPTO_AES_IV_LEN]; 49 ubyte[] aes_tag = new ubyte[CRYPTO_AES_TAG_LEN]; 50 51 52 if (!rand_salt(rand_iv, CRYPTO_AES_IV_LEN)) 53 { 54 return false; 55 } 56 57 bool ret = aes_encrypt(str_plaintext.ptr, cast(int)str_plaintext.length, peerkey.aes_key.ptr, rand_iv.ptr, str_ciphertext.ptr, aes_tag.ptr); 58 59 if (!ret) 60 { 61 return false; 62 } 63 64 65 ciphertext.cipher_version = cast(uint)str_plaintext.length; 66 ciphertext.aes_iv_12bytes = Base64.encode(rand_iv); 67 ciphertext.aes_tag_16bytes = Base64.encode(aes_tag); 68 ciphertext.ciphertext_nbytes = Base64.encode(str_ciphertext); 69 70 logInfo("cipher_version %s", ciphertext.cipher_version); 71 logInfo("aes_iv_12bytes %s", rand_iv); 72 logInfo("aes_tag_16bytes %s", aes_tag); 73 logInfo("ciphertext_nbytes %s", str_ciphertext); 74 logInfo("aes key:" ,peerkey.aes_key); 75 76 return true; 77 } 78 79 static bool generate_token(const ubyte[CRYPTO_EC_PUB_KEY_LEN] ecdh_pub_key, Token token) 80 { 81 ubyte[] random_digit = new ubyte[3]; 82 ubyte[] hmac_256 = new ubyte[CRYPTO_HMAC_SHA256]; 83 84 85 if (!rand_salt(random_digit, 3)) 86 { 87 logError("random digit generation error."); 88 return false; 89 } 90 91 if (!hmac_sha256(hmac_256, random_digit, 3, ecdh_pub_key, CRYPTO_EC_PUB_KEY_LEN)) 92 { 93 logError("hmac calculation error."); 94 return false; 95 } 96 97 token.salt_3bytes = Base64.encode(random_digit); 98 token.hmac_3bytes = Base64.encode(hmac_256); 99 100 logInfo("token.salt_3bytes %s",random_digit); 101 logInfo("token.salt_3bytes %s",token.salt_3bytes); 102 logInfo("token.hmac_3bytes %s",token.hmac_3bytes); 103 104 return true; 105 } 106 107 static bool verify_token(const ubyte[CRYPTO_EC_PUB_KEY_LEN] ecdh_pub_key, Token token) 108 { 109 ubyte[] hmac_256 = new ubyte[CRYPTO_HMAC_SHA256]; 110 ubyte[] dd = Base64.decode(token.salt_3bytes); 111 112 // logInfo("dd %s %d",dd ,cast(uint)token.salt_3bytes.length); 113 bool ret = hmac_sha256(hmac_256, Base64.decode(token.salt_3bytes), 3, ecdh_pub_key, CRYPTO_EC_PUB_KEY_LEN); 114 if (!ret) 115 { 116 logError("hmac calculation error."); 117 return false; 118 } 119 120 logInfo("hmac_256 %s",hmac_256); 121 logInfo("hmac_3bytes %s",token.hmac_3bytes); 122 logInfo("salt_3bytes %s",token.salt_3bytes); 123 124 if (0 != memcmp(Base64.decode(token.hmac_3bytes).ptr, hmac_256.ptr, 3)) 125 { 126 logError("Token check failed"); 127 return false; 128 } 129 130 return true; 131 } 132 133 static MessageBuffer encrypted_encode(MessageBuffer message ,ownkey_s client_key , peerkey_s server_key) 134 { 135 Ciphertext ciphertext = new Ciphertext; 136 Token token = new Token; 137 token.salt_3bytes = "1"; 138 token.hmac_3bytes = "1"; 139 EncryptedRequest encrypted_request = new EncryptedRequest; 140 if(!encrypt_plaintext(server_key, message.data, ciphertext)) 141 { 142 logError ("aes encryption error."); 143 return null; 144 } 145 if(client_key !is null) 146 { 147 if (!common.generate_token(client_key.ec_pub_key, token)) 148 { 149 logError("token generation error."); 150 return null; 151 } 152 } 153 logInfo("out salt_3bytes %s",token.salt_3bytes); 154 logInfo("out hmac_3bytes %s",token.hmac_3bytes); 155 encrypted_request.token = token; 156 encrypted_request.ciphertext = ciphertext; 157 logInfo("encrypted_request %s",encrypted_request.toProtobuf.array); 158 if (message.hasExtend) 159 { 160 return new MessageBuffer(message.id , encrypted_request.toProtobuf.array, message.extend); 161 }else 162 { 163 return new MessageBuffer(message.id , encrypted_request.toProtobuf.array); 164 } 165 } 166 167 static MessageBuffer encrypted_decode(MessageBuffer message, peerkey_s peer_key, bool isClient = false) 168 { 169 logInfo("encrypted_decode id: %s" ,message.id); 170 EncryptedRequest encrypted_request = new EncryptedRequest; 171 message.data.fromProtobuf!EncryptedRequest(encrypted_request); 172 173 if(!isClient) 174 { 175 if (!common.verify_token(peer_key.ec_pub_key, encrypted_request.token)) 176 { 177 logError("token check failed."); 178 return null; 179 } 180 } 181 182 logInfo("============================================================================"); 183 logInfo("msgId :%d" , message.id); 184 logInfo("cipher_version %s" , encrypted_request.ciphertext.cipher_version); 185 logInfo("base64 ciphertext_nbytes %s", encrypted_request.ciphertext.ciphertext_nbytes); 186 logInfo("base64 aes_tag_16bytes %s", encrypted_request.ciphertext.aes_tag_16bytes); 187 logInfo("base64 aes_iv_12bytes %s", encrypted_request.ciphertext.aes_iv_12bytes); 188 189 190 //uint len = encrypted_request.ciphertext.ciphertext_nbytes.length; 191 uint len = encrypted_request.ciphertext.cipher_version; 192 ubyte[] ciphertext_nbytes = Base64.decode(encrypted_request.ciphertext.ciphertext_nbytes); 193 ubyte[] plaintext = new ubyte[len]; 194 195 logInfo("ciphertext_nbytes %s", ciphertext_nbytes); 196 197 ubyte[] aes_tag_16bytes = Base64.decode(encrypted_request.ciphertext.aes_tag_16bytes); 198 199 logInfo("aes_tag_16bytes %s", aes_tag_16bytes); 200 if(len != 0) 201 { 202 bool ret = aes_decrypt(ciphertext_nbytes.ptr, 203 len, 204 aes_tag_16bytes.ptr, 205 peer_key.aes_key.ptr, 206 Base64.decode(encrypted_request.ciphertext.aes_iv_12bytes).ptr, plaintext.ptr); 207 if (!ret) 208 { 209 logError("aes decryption error"); 210 return null; 211 } 212 } 213 214 215 logInfo("aes_iv_12bytes %s", Base64.decode(encrypted_request.ciphertext.aes_iv_12bytes)); 216 217 logInfo("peer_key.aes_key.ptr %s" ,peer_key.aes_key); 218 219 220 if (message.hasExtend) 221 { 222 return new MessageBuffer(message.id , plaintext,message.extend); 223 }else 224 { 225 return new MessageBuffer(message.id , plaintext); 226 } 227 228 } 229 230 } 231