/src/mosquitto/common/password_mosq.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright (c) 2012-2021 Roger Light <roger@atchoo.org> |
3 | | |
4 | | All rights reserved. This program and the accompanying materials |
5 | | are made available under the terms of the Eclipse Public License 2.0 |
6 | | and Eclipse Distribution License v1.0 which accompany this distribution. |
7 | | |
8 | | The Eclipse Public License is available at |
9 | | https://www.eclipse.org/legal/epl-2.0/ |
10 | | and the Eclipse Distribution License is available at |
11 | | http://www.eclipse.org/org/documents/edl-v10.php. |
12 | | |
13 | | SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
14 | | |
15 | | Contributors: |
16 | | Roger Light - initial implementation and documentation. |
17 | | */ |
18 | | |
19 | | #include "config.h" |
20 | | |
21 | | #include <errno.h> |
22 | | #ifdef WITH_TLS |
23 | | # include <openssl/opensslv.h> |
24 | | # include <openssl/evp.h> |
25 | | # include <openssl/rand.h> |
26 | | # include <openssl/buffer.h> |
27 | | #endif |
28 | | #include <signal.h> |
29 | | #include <stdio.h> |
30 | | #include <stdlib.h> |
31 | | #include <string.h> |
32 | | |
33 | | #include "mosquitto.h" |
34 | | #include "mosquitto_broker.h" |
35 | | #include "password_mosq.h" |
36 | | |
37 | | #ifdef WIN32 |
38 | | # include <windows.h> |
39 | | # include <process.h> |
40 | | # ifndef __cplusplus |
41 | | # if defined(_MSC_VER) && _MSC_VER < 1900 |
42 | | # define bool char |
43 | | # define true 1 |
44 | | # define false 0 |
45 | | # else |
46 | | # include <stdbool.h> |
47 | | # endif |
48 | | # endif |
49 | | # define snprintf sprintf_s |
50 | | # include <io.h> |
51 | | # include <windows.h> |
52 | | #else |
53 | | # include <stdbool.h> |
54 | | # include <unistd.h> |
55 | | # include <termios.h> |
56 | | # include <sys/stat.h> |
57 | | #endif |
58 | | |
59 | | #ifdef WITH_TLS |
60 | | int pw__hash(const char *password, struct mosquitto_pw *pw, bool new_password, int new_iterations) |
61 | 18.7k | { |
62 | 18.7k | int rc; |
63 | 18.7k | unsigned int hash_len; |
64 | 18.7k | const EVP_MD *digest; |
65 | 18.7k | int iterations; |
66 | | #if OPENSSL_VERSION_NUMBER < 0x10100000L |
67 | | EVP_MD_CTX context; |
68 | | #else |
69 | 18.7k | EVP_MD_CTX *context; |
70 | 18.7k | #endif |
71 | | |
72 | 18.7k | if(new_password){ |
73 | 18.7k | pw->salt_len = HASH_LEN; |
74 | 18.7k | rc = RAND_bytes(pw->salt, (int)pw->salt_len); |
75 | 18.7k | if(!rc){ |
76 | 0 | return MOSQ_ERR_UNKNOWN; |
77 | 0 | } |
78 | 18.7k | iterations = new_iterations; |
79 | 18.7k | }else{ |
80 | 0 | iterations = pw->iterations; |
81 | 0 | } |
82 | 18.7k | if(iterations < 1){ |
83 | 0 | return MOSQ_ERR_INVAL; |
84 | 0 | } |
85 | | |
86 | 18.7k | digest = EVP_get_digestbyname("sha512"); |
87 | 18.7k | if(!digest){ |
88 | 0 | return MOSQ_ERR_UNKNOWN; |
89 | 0 | } |
90 | | |
91 | 18.7k | if(pw->hashtype == pw_sha512){ |
92 | | #if OPENSSL_VERSION_NUMBER < 0x10100000L |
93 | | EVP_MD_CTX_init(&context); |
94 | | EVP_DigestInit_ex(&context, digest, NULL); |
95 | | EVP_DigestUpdate(&context, password, strlen(password)); |
96 | | EVP_DigestUpdate(&context, pw->salt, pw->salt_len); |
97 | | EVP_DigestFinal_ex(&context, pw->password_hash, &hash_len); |
98 | | EVP_MD_CTX_cleanup(&context); |
99 | | #else |
100 | 0 | context = EVP_MD_CTX_new(); |
101 | 0 | EVP_DigestInit_ex(context, digest, NULL); |
102 | 0 | EVP_DigestUpdate(context, password, strlen(password)); |
103 | 0 | EVP_DigestUpdate(context, pw->salt, pw->salt_len); |
104 | 0 | EVP_DigestFinal_ex(context, pw->password_hash, &hash_len); |
105 | 0 | EVP_MD_CTX_free(context); |
106 | 0 | #endif |
107 | 18.7k | }else{ |
108 | 18.7k | pw->iterations = iterations; |
109 | 18.7k | hash_len = sizeof(pw->password_hash); |
110 | 18.7k | PKCS5_PBKDF2_HMAC(password, (int)strlen(password), |
111 | 18.7k | pw->salt, (int)pw->salt_len, iterations, |
112 | 18.7k | digest, (int)hash_len, pw->password_hash); |
113 | 18.7k | } |
114 | | |
115 | 18.7k | return MOSQ_ERR_SUCCESS; |
116 | 18.7k | } |
117 | | #endif |
118 | | |
119 | | int pw__memcmp_const(const void *a, const void *b, size_t len) |
120 | 0 | { |
121 | 0 | size_t i; |
122 | 0 | int rc = 0; |
123 | |
|
124 | 0 | if(!a || !b) return 1; |
125 | | |
126 | 0 | for(i=0; i<len; i++){ |
127 | 0 | if( ((char *)a)[i] != ((char *)b)[i] ){ |
128 | 0 | rc = 1; |
129 | 0 | } |
130 | 0 | } |
131 | 0 | return rc; |
132 | 0 | } |