/*! * \internal * \brief Add a new cipher to the transport's cipher list array. * * \param transport Which transport to add the cipher to. * \param name Cipher identifier name. * * \retval 0 on success. * \retval -1 on error. */ static int transport_cipher_add(struct ast_sip_transport_state *state, const char *name) { pj_ssl_cipher cipher; int idx; cipher = cipher_name_to_id(name); if (!cipher) { /* TODO: Check this over/tweak - it's taken from pjsua for now */ if (!strnicmp(name, "0x", 2)) { pj_str_t cipher_st = pj_str((char *) name + 2); cipher = pj_strtoul2(&cipher_st, NULL, 16); } else { cipher = atoi(name); } } if (pj_ssl_cipher_is_supported(cipher)) { for (idx = state->tls.ciphers_num; idx--;) { if (state->ciphers[idx] == cipher) { /* The cipher is already in the list. */ return 0; } } state->ciphers[state->tls.ciphers_num++] = cipher; return 0; } else { ast_log(LOG_ERROR, "Cipher '%s' is unsupported\n", name); return -1; } }
/** Constructor. * @param key encryption key, can be any string, will be processed to meet * the cipher's requirements. * @param cipher_name Cipher combination to use, currently supported are * aes-128-ecb, aes-128-cbc, aes-256-ecb, and aes-256-cbc */ BufferEncryptor::BufferEncryptor(const std::string &key, std::string cipher_name) { #ifdef HAVE_LIBCRYPTO cipher_ = cipher_by_name(cipher_name.c_str()); cipher_id_ = cipher_name_to_id(cipher_name.c_str()); const size_t key_size = EVP_CIPHER_key_length(cipher_); const size_t iv_size = EVP_CIPHER_iv_length(cipher_); key_ = (unsigned char *)malloc(key_size); unsigned char iv[iv_size]; if( ! EVP_BytesToKey(cipher_, EVP_sha256(), NULL, (const unsigned char *)key.c_str(), key.size(), 8, key_, iv)) { throw std::runtime_error("Failed to generate key"); } if (!RAND_bytes((unsigned char *)&iv_, sizeof(iv_))) { throw std::runtime_error("Failed to generate IV"); } #else throw std::runtime_error("Encryption support not available"); #endif }