/*!
 * make a keyed-hash from a key using the HMAC-sha256 and a challenge
 *
 * \param key The key to make a digest for
 * \param challenge Some data mixin - identify the specific digest
 * \return a base64 encoded digest
 */
inline std::string compute_wcs(
        const std::string & key,
        const std::string & challenge )
{

    unsigned int len = 32;
    unsigned char hash[32];
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
    HMAC_CTX hmac;
    HMAC_CTX_init(&hmac);
    HMAC_Init_ex(&hmac, key.data(), key.length(), EVP_sha256(), NULL);
    HMAC_Update(&hmac, (unsigned char*) challenge.data(), challenge.length());
    HMAC_Final(&hmac, hash, &len);
    HMAC_CTX_cleanup(&hmac);
#else
    HMAC_CTX *hmac = HMAC_CTX_new();
    if (!hmac)
        return "";
    HMAC_Init_ex(hmac, key.data(), key.length(), EVP_sha256(), NULL);
    HMAC_Update(hmac, ( unsigned char* ) challenge.data(), challenge.length());
    HMAC_Final(hmac, hash, &len);
    HMAC_CTX_free(hmac);
#endif

    std::string str_out;
    str_out.assign( ( char * ) &hash , 32 );

    return base_64_encode( str_out );
}
Esempio n. 2
0
bool encode_request(const uint8_t *req, uint32_t req_len, uint8_t *out_buf, uint32_t *out_len)
{
    uint32_t encoded_header_size = static_cast<uint32_t>(2*PROVISION_REQUEST_HEADER_SIZE);
    if(*out_len<encoded_header_size)
        return false;
    if(req_len<PROVISION_REQUEST_HEADER_SIZE)
        return false;
    if(!byte_array_to_hex_string(req, PROVISION_REQUEST_HEADER_SIZE, out_buf, encoded_header_size))
        return false;
    uint32_t left_size = *out_len - encoded_header_size;
    if(req_len != GET_SIZE_FROM_PROVISION_REQUEST(req))
        return false;//error in input message
    if(!base_64_encode(req+PROVISION_REQUEST_HEADER_SIZE, GET_BODY_SIZE_FROM_PROVISION_REQUEST(req), out_buf + encoded_header_size, &left_size))
        return false;
    *out_len = left_size + encoded_header_size;
    return true;
}
/*!
 * create a derived key from a password/secret
 *
 * \param  passwd A secret string to make a derived key for
 * \param  salt A random salt added to the key
 * \param  iterations A number of intertions used to create the derived key
 * \param  keylen The length of the derived key returned.
 * \return a PBKDF2-sha256 derived key
 */
inline std::string derive_key(
        const std::string & passwd,
        const std::string & salt,
        int iterations,
        int keylen
        )
{

    int passwdLen = passwd.size();
    const char * pwd = passwd.c_str();

    int saltLen = salt.size();
    unsigned char * salt_value = (unsigned char * ) salt.c_str();

    std::string str_out;
    str_out.resize( keylen );


    unsigned char * out = (unsigned char *) str_out.c_str();


    int result = PKCS5_PBKDF2_HMAC(
            pwd, passwdLen,
            salt_value, saltLen,
            iterations,
            EVP_sha256(),
            keylen, out);

    if ( result != 0 )
    {
        return base_64_encode( str_out );
    }
    else
    {
        throw derived_key_error();
    }
}