Add support for PBKDF2-SHA512 password hashing.
This commit is contained in:
parent
c927446264
commit
5371bd09d1
@ -46,6 +46,7 @@ Broker:
|
|||||||
- Add `mosquitto_kick_client_by_clientid()` and `mosquitto_kick_client_by_username()`
|
- Add `mosquitto_kick_client_by_clientid()` and `mosquitto_kick_client_by_username()`
|
||||||
functions, which can be used by plugins to disconnect clients.
|
functions, which can be used by plugins to disconnect clients.
|
||||||
- Add support for handling $CONTROL/ topics in plugins.
|
- Add support for handling $CONTROL/ topics in plugins.
|
||||||
|
- Add support for PBKDF2-SHA512 password hashing.
|
||||||
|
|
||||||
Client library:
|
Client library:
|
||||||
- Client no longer generates random client ids for v3.1.1 clients, these are
|
- Client no longer generates random client ids for v3.1.1 clients, these are
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
<command>mosquitto_passwd</command>
|
<command>mosquitto_passwd</command>
|
||||||
|
<group>
|
||||||
|
<arg choice='plain'><option>-H</option> <replaceable>hash</replaceable></arg>
|
||||||
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<arg choice='plain'><option>-c</option></arg>
|
<arg choice='plain'><option>-c</option></arg>
|
||||||
<arg choice='plain'><option>-D</option></arg>
|
<arg choice='plain'><option>-D</option></arg>
|
||||||
@ -26,6 +29,9 @@
|
|||||||
</cmdsynopsis>
|
</cmdsynopsis>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
<command>mosquitto_passwd</command>
|
<command>mosquitto_passwd</command>
|
||||||
|
<group>
|
||||||
|
<arg choice='plain'><option>-H</option> <replaceable>hash</replaceable></arg>
|
||||||
|
</group>
|
||||||
<arg choice='plain'><option>-b</option></arg>
|
<arg choice='plain'><option>-b</option></arg>
|
||||||
<arg choice='plain'><replaceable>passwordfile</replaceable></arg>
|
<arg choice='plain'><replaceable>passwordfile</replaceable></arg>
|
||||||
<arg choice='plain'><replaceable>username</replaceable></arg>
|
<arg choice='plain'><replaceable>username</replaceable></arg>
|
||||||
@ -74,6 +80,18 @@
|
|||||||
file.</para>
|
file.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-H</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Choose the hash to use. Can be one of
|
||||||
|
<replaceable>sha512-pbkdf2</replaceable> or
|
||||||
|
<replaceable>sha512</replaceable>. Defaults to
|
||||||
|
<replaceable>sha512-pbkdf2</replaceable>. The
|
||||||
|
<replaceable>sha512</replaceable> option is provided for
|
||||||
|
creating password files for use with Mosquitto 1.6
|
||||||
|
and earlier.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-U</option></term>
|
<term><option>-U</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -174,6 +174,11 @@ enum mosquitto_msg_origin{
|
|||||||
mosq_mo_broker = 1
|
mosq_mo_broker = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum mosquitto_pwhash_type{
|
||||||
|
pw_sha512 = 6,
|
||||||
|
pw_sha512_pbkdf2 = 7
|
||||||
|
};
|
||||||
|
|
||||||
struct mosquitto__auth_plugin{
|
struct mosquitto__auth_plugin{
|
||||||
void *lib;
|
void *lib;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
@ -449,14 +454,15 @@ struct mosquitto_client_msg{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mosquitto__unpwd{
|
struct mosquitto__unpwd{
|
||||||
|
UT_hash_handle hh;
|
||||||
char *username;
|
char *username;
|
||||||
char *password;
|
char *password;
|
||||||
#ifdef WITH_TLS
|
#ifdef WITH_TLS
|
||||||
|
unsigned char *salt;
|
||||||
unsigned int password_len;
|
unsigned int password_len;
|
||||||
unsigned int salt_len;
|
unsigned int salt_len;
|
||||||
unsigned char *salt;
|
|
||||||
#endif
|
#endif
|
||||||
UT_hash_handle hh;
|
enum mosquitto_pwhash_type hashtype;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mosquitto__acl{
|
struct mosquitto__acl{
|
||||||
|
@ -54,6 +54,11 @@ Contributors:
|
|||||||
|
|
||||||
#include "misc_mosq.h"
|
#include "misc_mosq.h"
|
||||||
|
|
||||||
|
enum pwhash{
|
||||||
|
pw_sha512 = 6,
|
||||||
|
pw_sha512_pbkdf2 = 7,
|
||||||
|
};
|
||||||
|
|
||||||
struct cb_helper {
|
struct cb_helper {
|
||||||
const char *line;
|
const char *line;
|
||||||
const char *username;
|
const char *username;
|
||||||
@ -69,6 +74,7 @@ static FILE *mpw_tmpfile(void)
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
static char alphanum[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
static char alphanum[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
static enum pwhash hashtype = pw_sha512_pbkdf2;
|
||||||
|
|
||||||
static unsigned char tmpfile_path[36];
|
static unsigned char tmpfile_path[36];
|
||||||
static FILE *mpw_tmpfile(void)
|
static FILE *mpw_tmpfile(void)
|
||||||
@ -132,12 +138,14 @@ int base64_encode(unsigned char *in, unsigned int in_len, char **encoded)
|
|||||||
void print_usage(void)
|
void print_usage(void)
|
||||||
{
|
{
|
||||||
printf("mosquitto_passwd is a tool for managing password files for mosquitto.\n\n");
|
printf("mosquitto_passwd is a tool for managing password files for mosquitto.\n\n");
|
||||||
printf("Usage: mosquitto_passwd [-c | -D] passwordfile username\n");
|
printf("Usage: mosquitto_passwd [-H sha512 | -H sha512-pbkdf2] [-c | -D] passwordfile username\n");
|
||||||
printf(" mosquitto_passwd -b passwordfile username password\n");
|
printf(" mosquitto_passwd [-H sha512 | -H sha512-pbkdf2] -b passwordfile username password\n");
|
||||||
printf(" mosquitto_passwd -U passwordfile\n");
|
printf(" mosquitto_passwd -U passwordfile\n");
|
||||||
printf(" -b : run in batch mode to allow passing passwords on the command line.\n");
|
printf(" -b : run in batch mode to allow passing passwords on the command line.\n");
|
||||||
printf(" -c : create a new password file. This will overwrite existing files.\n");
|
printf(" -c : create a new password file. This will overwrite existing files.\n");
|
||||||
printf(" -D : delete the username rather than adding/updating its password.\n");
|
printf(" -D : delete the username rather than adding/updating its password.\n");
|
||||||
|
printf(" -H : specify the hashing algorithm. Defaults to sha512-pbkdf2, which is recommended.\n");
|
||||||
|
printf(" Mosquitto 1.6 and earlier defaulted to sha512.\n");
|
||||||
printf(" -U : update a plain text password file to use hashed passwords.\n");
|
printf(" -U : update a plain text password file to use hashed passwords.\n");
|
||||||
printf("\nSee https://mosquitto.org/ for more information.\n\n");
|
printf("\nSee https://mosquitto.org/ for more information.\n\n");
|
||||||
}
|
}
|
||||||
@ -177,21 +185,28 @@ int output_new_password(FILE *fptr, const char *username, const char *password)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(hashtype == pw_sha512){
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
EVP_MD_CTX_init(&context);
|
EVP_MD_CTX_init(&context);
|
||||||
EVP_DigestInit_ex(&context, digest, NULL);
|
EVP_DigestInit_ex(&context, digest, NULL);
|
||||||
EVP_DigestUpdate(&context, password, strlen(password));
|
EVP_DigestUpdate(&context, password, strlen(password));
|
||||||
EVP_DigestUpdate(&context, salt, SALT_LEN);
|
EVP_DigestUpdate(&context, salt, SALT_LEN);
|
||||||
EVP_DigestFinal_ex(&context, hash, &hash_len);
|
EVP_DigestFinal_ex(&context, hash, &hash_len);
|
||||||
EVP_MD_CTX_cleanup(&context);
|
EVP_MD_CTX_cleanup(&context);
|
||||||
#else
|
#else
|
||||||
context = EVP_MD_CTX_new();
|
context = EVP_MD_CTX_new();
|
||||||
EVP_DigestInit_ex(context, digest, NULL);
|
EVP_DigestInit_ex(context, digest, NULL);
|
||||||
EVP_DigestUpdate(context, password, strlen(password));
|
EVP_DigestUpdate(context, password, strlen(password));
|
||||||
EVP_DigestUpdate(context, salt, SALT_LEN);
|
EVP_DigestUpdate(context, salt, SALT_LEN);
|
||||||
EVP_DigestFinal_ex(context, hash, &hash_len);
|
EVP_DigestFinal_ex(context, hash, &hash_len);
|
||||||
EVP_MD_CTX_free(context);
|
EVP_MD_CTX_free(context);
|
||||||
#endif
|
#endif
|
||||||
|
}else{
|
||||||
|
hash_len = sizeof(hash);
|
||||||
|
PKCS5_PBKDF2_HMAC(password, strlen(password),
|
||||||
|
salt, SALT_LEN, 20000,
|
||||||
|
digest, hash_len, hash);
|
||||||
|
}
|
||||||
|
|
||||||
rc = base64_encode(hash, hash_len, &hash64);
|
rc = base64_encode(hash, hash_len, &hash64);
|
||||||
if(rc){
|
if(rc){
|
||||||
@ -201,7 +216,7 @@ int output_new_password(FILE *fptr, const char *username, const char *password)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fptr, "%s:$6$%s$%s\n", username, salt64, hash64);
|
fprintf(fptr, "%s:$%d$%s$%s\n", username, hashtype, salt64, hash64);
|
||||||
free(salt64);
|
free(salt64);
|
||||||
free(hash64);
|
free(hash64);
|
||||||
|
|
||||||
@ -331,10 +346,8 @@ static int update_pwuser_cb(FILE *fptr, FILE *ftmp, const char *username, const
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
printf("%s\n", username);
|
|
||||||
if(strcmp(username, helper->username)){
|
if(strcmp(username, helper->username)){
|
||||||
/* If this isn't the matching user, then writing out the exiting line */
|
/* If this isn't the matching user, then writing out the exiting line */
|
||||||
printf("%s\n", line);
|
|
||||||
fprintf(ftmp, "%s", line);
|
fprintf(ftmp, "%s", line);
|
||||||
}else{
|
}else{
|
||||||
/* Write out a new line for our matching username */
|
/* Write out a new line for our matching username */
|
||||||
@ -520,6 +533,7 @@ int main(int argc, char *argv[])
|
|||||||
int rc;
|
int rc;
|
||||||
bool do_update_file = false;
|
bool do_update_file = false;
|
||||||
char *backup_file;
|
char *backup_file;
|
||||||
|
int idx;
|
||||||
|
|
||||||
signal(SIGINT, handle_sigint);
|
signal(SIGINT, handle_sigint);
|
||||||
signal(SIGTERM, handle_sigint);
|
signal(SIGTERM, handle_sigint);
|
||||||
@ -537,45 +551,63 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcmp(argv[1], "-c")){
|
idx = 1;
|
||||||
|
if(!strcmp(argv[1], "-H")){
|
||||||
|
if(argc < 5){
|
||||||
|
fprintf(stderr, "Error: -H argument given but not enough other arguments.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(!strcmp(argv[2], "sha512")){
|
||||||
|
hashtype = pw_sha512;
|
||||||
|
}else if(!strcmp(argv[2], "sha512-pbkdf2")){
|
||||||
|
hashtype = pw_sha512_pbkdf2;
|
||||||
|
}else{
|
||||||
|
fprintf(stderr, "Error: Unknown hash type '%s'\n", argv[2]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
idx += 2;
|
||||||
|
argc -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!strcmp(argv[idx], "-c")){
|
||||||
create_new = true;
|
create_new = true;
|
||||||
if(argc != 4){
|
if(argc != 4){
|
||||||
fprintf(stderr, "Error: -c argument given but password file or username missing.\n");
|
fprintf(stderr, "Error: -c argument given but password file or username missing.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}else{
|
}else{
|
||||||
password_file_tmp = argv[2];
|
password_file_tmp = argv[idx+1];
|
||||||
username = argv[3];
|
username = argv[idx+2];
|
||||||
}
|
}
|
||||||
}else if(!strcmp(argv[1], "-D")){
|
}else if(!strcmp(argv[idx], "-D")){
|
||||||
delete_user = true;
|
delete_user = true;
|
||||||
if(argc != 4){
|
if(argc != 4){
|
||||||
fprintf(stderr, "Error: -D argument given but password file or username missing.\n");
|
fprintf(stderr, "Error: -D argument given but password file or username missing.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}else{
|
}else{
|
||||||
password_file_tmp = argv[2];
|
password_file_tmp = argv[idx+1];
|
||||||
username = argv[3];
|
username = argv[idx+2];
|
||||||
}
|
}
|
||||||
}else if(!strcmp(argv[1], "-b")){
|
}else if(!strcmp(argv[idx], "-b")){
|
||||||
batch_mode = true;
|
batch_mode = true;
|
||||||
if(argc != 5){
|
if(argc != 5){
|
||||||
fprintf(stderr, "Error: -b argument given but password file, username or password missing.\n");
|
fprintf(stderr, "Error: -b argument given but password file, username or password missing.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}else{
|
}else{
|
||||||
password_file_tmp = argv[2];
|
password_file_tmp = argv[idx+1];
|
||||||
username = argv[3];
|
username = argv[idx+2];
|
||||||
password_cmd = argv[4];
|
password_cmd = argv[idx+3];
|
||||||
}
|
}
|
||||||
}else if(!strcmp(argv[1], "-U")){
|
}else if(!strcmp(argv[idx], "-U")){
|
||||||
if(argc != 3){
|
if(argc != 3){
|
||||||
fprintf(stderr, "Error: -U argument given but password file missing.\n");
|
fprintf(stderr, "Error: -U argument given but password file missing.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}else{
|
}else{
|
||||||
do_update_file = true;
|
do_update_file = true;
|
||||||
password_file_tmp = argv[2];
|
password_file_tmp = argv[idx+1];
|
||||||
}
|
}
|
||||||
}else if(argc == 3){
|
}else if(argc == 3){
|
||||||
password_file_tmp = argv[1];
|
password_file_tmp = argv[idx];
|
||||||
username = argv[2];
|
username = argv[idx+1];
|
||||||
}else{
|
}else{
|
||||||
print_usage();
|
print_usage();
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -33,7 +33,7 @@ static int acl__cleanup(struct mosquitto_db *db, bool reload);
|
|||||||
static int unpwd__cleanup(struct mosquitto__unpwd **unpwd, bool reload);
|
static int unpwd__cleanup(struct mosquitto__unpwd **unpwd, bool reload);
|
||||||
static int psk__file_parse(struct mosquitto_db *db, struct mosquitto__unpwd **psk_id, const char *psk_file);
|
static int psk__file_parse(struct mosquitto_db *db, struct mosquitto__unpwd **psk_id, const char *psk_file);
|
||||||
#ifdef WITH_TLS
|
#ifdef WITH_TLS
|
||||||
static int pw__digest(const char *password, const unsigned char *salt, unsigned int salt_len, unsigned char *hash, unsigned int *hash_len);
|
static int pw__digest(const char *password, const unsigned char *salt, unsigned int salt_len, unsigned char *hash, unsigned int *hash_len, enum mosquitto_pwhash_type hashtype);
|
||||||
static int base64__decode(char *in, unsigned char **decoded, unsigned int *decoded_len);
|
static int base64__decode(char *in, unsigned char **decoded, unsigned int *decoded_len);
|
||||||
static int mosquitto__memcmp_const(const void *ptr1, const void *b, size_t len);
|
static int mosquitto__memcmp_const(const void *ptr1, const void *b, size_t len);
|
||||||
#endif
|
#endif
|
||||||
@ -773,12 +773,22 @@ static int unpwd__decode_passwords(struct mosquitto__unpwd **unpwd)
|
|||||||
unsigned char *password;
|
unsigned char *password;
|
||||||
unsigned int password_len;
|
unsigned int password_len;
|
||||||
int rc;
|
int rc;
|
||||||
|
int hashtype;
|
||||||
|
|
||||||
HASH_ITER(hh, *unpwd, u, tmp){
|
HASH_ITER(hh, *unpwd, u, tmp){
|
||||||
/* Need to decode password into hashed data + salt. */
|
/* Need to decode password into hashed data + salt. */
|
||||||
if(u->password){
|
if(u->password){
|
||||||
token = strtok(u->password, "$");
|
token = strtok(u->password, "$");
|
||||||
if(token && !strcmp(token, "6")){
|
if(token){
|
||||||
|
if(!strcmp(token, "6")){
|
||||||
|
hashtype = pw_sha512;
|
||||||
|
}else if(!strcmp(token, "7")){
|
||||||
|
hashtype = pw_sha512_pbkdf2;
|
||||||
|
}else{
|
||||||
|
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid password hash type for user %s, removing entry.", u->username);
|
||||||
|
unpwd__free_item(unpwd, u);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
token = strtok(NULL, "$");
|
token = strtok(NULL, "$");
|
||||||
if(token){
|
if(token){
|
||||||
rc = base64__decode(token, &salt, &salt_len);
|
rc = base64__decode(token, &salt, &salt_len);
|
||||||
@ -792,6 +802,7 @@ static int unpwd__decode_passwords(struct mosquitto__unpwd **unpwd)
|
|||||||
mosquitto__free(u->password);
|
mosquitto__free(u->password);
|
||||||
u->password = (char *)password;
|
u->password = (char *)password;
|
||||||
u->password_len = password_len;
|
u->password_len = password_len;
|
||||||
|
u->hashtype = hashtype;
|
||||||
}else{
|
}else{
|
||||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to decode password for user %s, removing entry.", u->username);
|
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to decode password for user %s, removing entry.", u->username);
|
||||||
unpwd__free_item(unpwd, u);
|
unpwd__free_item(unpwd, u);
|
||||||
@ -953,7 +964,7 @@ int mosquitto_unpwd_check_default(struct mosquitto_db *db, struct mosquitto *con
|
|||||||
if(u->password){
|
if(u->password){
|
||||||
if(context->password){
|
if(context->password){
|
||||||
#ifdef WITH_TLS
|
#ifdef WITH_TLS
|
||||||
rc = pw__digest(context->password, u->salt, u->salt_len, hash, &hash_len);
|
rc = pw__digest(context->password, u->salt, u->salt_len, hash, &hash_len, u->hashtype);
|
||||||
if(rc == MOSQ_ERR_SUCCESS){
|
if(rc == MOSQ_ERR_SUCCESS){
|
||||||
if(hash_len == u->password_len && !mosquitto__memcmp_const(u->password, hash, hash_len)){
|
if(hash_len == u->password_len && !mosquitto__memcmp_const(u->password, hash, hash_len)){
|
||||||
return MOSQ_ERR_SUCCESS;
|
return MOSQ_ERR_SUCCESS;
|
||||||
@ -1250,27 +1261,14 @@ int mosquitto_psk_key_get_default(struct mosquitto_db *db, struct mosquitto *con
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_TLS
|
#ifdef WITH_TLS
|
||||||
int pw__digest(const char *password, const unsigned char *salt, unsigned int salt_len, unsigned char *hash, unsigned int *hash_len)
|
int pw__digest(const char *password, const unsigned char *salt, unsigned int salt_len, unsigned char *hash, unsigned int *hash_len, enum mosquitto_pwhash_type hashtype)
|
||||||
{
|
{
|
||||||
const EVP_MD *digest;
|
const EVP_MD *digest;
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
EVP_MD_CTX context;
|
EVP_MD_CTX context;
|
||||||
|
|
||||||
digest = EVP_get_digestbyname("sha512");
|
|
||||||
if(!digest){
|
|
||||||
// FIXME fprintf(stderr, "Error: Unable to create openssl digest.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
EVP_MD_CTX_init(&context);
|
|
||||||
EVP_DigestInit_ex(&context, digest, NULL);
|
|
||||||
EVP_DigestUpdate(&context, password, strlen(password));
|
|
||||||
EVP_DigestUpdate(&context, salt, salt_len);
|
|
||||||
/* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */
|
|
||||||
EVP_DigestFinal_ex(&context, hash, hash_len);
|
|
||||||
EVP_MD_CTX_cleanup(&context);
|
|
||||||
#else
|
#else
|
||||||
EVP_MD_CTX *context;
|
EVP_MD_CTX *context;
|
||||||
|
#endif
|
||||||
|
|
||||||
digest = EVP_get_digestbyname("sha512");
|
digest = EVP_get_digestbyname("sha512");
|
||||||
if(!digest){
|
if(!digest){
|
||||||
@ -1278,14 +1276,30 @@ int pw__digest(const char *password, const unsigned char *salt, unsigned int sal
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context = EVP_MD_CTX_new();
|
if(hashtype == pw_sha512){
|
||||||
EVP_DigestInit_ex(context, digest, NULL);
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
EVP_DigestUpdate(context, password, strlen(password));
|
EVP_MD_CTX_init(&context);
|
||||||
EVP_DigestUpdate(context, salt, salt_len);
|
EVP_DigestInit_ex(&context, digest, NULL);
|
||||||
/* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */
|
EVP_DigestUpdate(&context, password, strlen(password));
|
||||||
EVP_DigestFinal_ex(context, hash, hash_len);
|
EVP_DigestUpdate(&context, salt, salt_len);
|
||||||
EVP_MD_CTX_free(context);
|
/* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */
|
||||||
|
EVP_DigestFinal_ex(&context, hash, hash_len);
|
||||||
|
EVP_MD_CTX_cleanup(&context);
|
||||||
|
#else
|
||||||
|
context = EVP_MD_CTX_new();
|
||||||
|
EVP_DigestInit_ex(context, digest, NULL);
|
||||||
|
EVP_DigestUpdate(context, password, strlen(password));
|
||||||
|
EVP_DigestUpdate(context, salt, salt_len);
|
||||||
|
/* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */
|
||||||
|
EVP_DigestFinal_ex(context, hash, hash_len);
|
||||||
|
EVP_MD_CTX_free(context);
|
||||||
#endif
|
#endif
|
||||||
|
}else{
|
||||||
|
*hash_len = EVP_MAX_MD_SIZE;
|
||||||
|
PKCS5_PBKDF2_HMAC(password, strlen(password),
|
||||||
|
salt, salt_len, 20000,
|
||||||
|
digest, *hash_len, hash);
|
||||||
|
}
|
||||||
|
|
||||||
return MOSQ_ERR_SUCCESS;
|
return MOSQ_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user