Lines 96-101
static algorithm_option_t algorithm_options[] = {
Link Here
|
96 |
{NULL, 0, NULL} |
96 |
{NULL, 0, NULL} |
97 |
}; |
97 |
}; |
98 |
|
98 |
|
|
|
99 |
static EVP_MD_CTX *_plug_EVP_MD_CTX_new(const sasl_utils_t *utils) |
100 |
{ |
101 |
utils->log(NULL, SASL_LOG_DEBUG, "_plug_EVP_MD_CTX_new()"); |
102 |
|
103 |
#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
104 |
return EVP_MD_CTX_new(); |
105 |
#else |
106 |
return utils->malloc(sizeof(EVP_MD_CTX)); |
107 |
#endif |
108 |
} |
109 |
|
110 |
static void _plug_EVP_MD_CTX_free(EVP_MD_CTX *ctx, const sasl_utils_t *utils) |
111 |
{ |
112 |
utils->log(NULL, SASL_LOG_DEBUG, "_plug_EVP_MD_CTX_free()"); |
113 |
|
114 |
#if OPENSSL_VERSION_NUMBER >= 0x10100000L |
115 |
EVP_MD_CTX_free(ctx); |
116 |
#else |
117 |
utils->free(ctx); |
118 |
#endif |
119 |
} |
120 |
|
99 |
/* Convert the binary data into ASCII hex */ |
121 |
/* Convert the binary data into ASCII hex */ |
100 |
void bin2hex(unsigned char *bin, int binlen, char *hex) |
122 |
void bin2hex(unsigned char *bin, int binlen, char *hex) |
101 |
{ |
123 |
{ |
Lines 116-132
void bin2hex(unsigned char *bin, int binlen, char *hex)
Link Here
|
116 |
* swabbing bytes if necessary. |
138 |
* swabbing bytes if necessary. |
117 |
*/ |
139 |
*/ |
118 |
static void otp_hash(const EVP_MD *md, char *in, size_t inlen, |
140 |
static void otp_hash(const EVP_MD *md, char *in, size_t inlen, |
119 |
unsigned char *out, int swab) |
141 |
unsigned char *out, int swab, EVP_MD_CTX *mdctx) |
120 |
{ |
142 |
{ |
121 |
EVP_MD_CTX mdctx; |
|
|
122 |
char hash[EVP_MAX_MD_SIZE]; |
143 |
char hash[EVP_MAX_MD_SIZE]; |
123 |
unsigned int i; |
144 |
unsigned int i; |
124 |
int j; |
145 |
int j; |
125 |
unsigned hashlen; |
146 |
unsigned hashlen; |
126 |
|
147 |
|
127 |
EVP_DigestInit(&mdctx, md); |
148 |
EVP_DigestInit(mdctx, md); |
128 |
EVP_DigestUpdate(&mdctx, in, inlen); |
149 |
EVP_DigestUpdate(mdctx, in, inlen); |
129 |
EVP_DigestFinal(&mdctx, hash, &hashlen); |
150 |
EVP_DigestFinal(mdctx, hash, &hashlen); |
130 |
|
151 |
|
131 |
/* Fold the result into 64 bits */ |
152 |
/* Fold the result into 64 bits */ |
132 |
for (i = OTP_HASH_SIZE; i < hashlen; i++) { |
153 |
for (i = OTP_HASH_SIZE; i < hashlen; i++) { |
Lines 149-155
static int generate_otp(const sasl_utils_t *utils,
Link Here
|
149 |
char *secret, char *otp) |
170 |
char *secret, char *otp) |
150 |
{ |
171 |
{ |
151 |
const EVP_MD *md; |
172 |
const EVP_MD *md; |
152 |
char *key; |
173 |
EVP_MD_CTX *mdctx = NULL; |
|
|
174 |
char *key = NULL; |
175 |
int r = SASL_OK; |
153 |
|
176 |
|
154 |
if (!(md = EVP_get_digestbyname(alg->evp_name))) { |
177 |
if (!(md = EVP_get_digestbyname(alg->evp_name))) { |
155 |
utils->seterror(utils->conn, 0, |
178 |
utils->seterror(utils->conn, 0, |
Lines 157-179
static int generate_otp(const sasl_utils_t *utils,
Link Here
|
157 |
return SASL_FAIL; |
180 |
return SASL_FAIL; |
158 |
} |
181 |
} |
159 |
|
182 |
|
|
|
183 |
if ((mdctx = _plug_EVP_MD_CTX_new(utils)) == NULL) { |
184 |
SETERROR(utils, "cannot allocate MD CTX"); |
185 |
r = SASL_NOMEM; |
186 |
goto done; |
187 |
} |
188 |
|
160 |
if ((key = utils->malloc(strlen(seed) + strlen(secret) + 1)) == NULL) { |
189 |
if ((key = utils->malloc(strlen(seed) + strlen(secret) + 1)) == NULL) { |
161 |
SETERROR(utils, "cannot allocate OTP key"); |
190 |
SETERROR(utils, "cannot allocate OTP key"); |
162 |
return SASL_NOMEM; |
191 |
r = SASL_NOMEM; |
|
|
192 |
goto done; |
163 |
} |
193 |
} |
164 |
|
194 |
|
165 |
/* initial step */ |
195 |
/* initial step */ |
166 |
strcpy(key, seed); |
196 |
strcpy(key, seed); |
167 |
strcat(key, secret); |
197 |
strcat(key, secret); |
168 |
otp_hash(md, key, strlen(key), otp, alg->swab); |
198 |
otp_hash(md, key, strlen(key), otp, alg->swab, mdctx); |
169 |
|
199 |
|
170 |
/* computation step */ |
200 |
/* computation step */ |
171 |
while (seq-- > 0) |
201 |
while (seq-- > 0) |
172 |
otp_hash(md, otp, OTP_HASH_SIZE, otp, alg->swab); |
202 |
otp_hash(md, otp, OTP_HASH_SIZE, otp, alg->swab, mdctx); |
173 |
|
203 |
|
174 |
utils->free(key); |
204 |
done: |
|
|
205 |
if (key) utils->free(key); |
206 |
if (mdctx) _plug_EVP_MD_CTX_free(mdctx, utils); |
175 |
|
207 |
|
176 |
return SASL_OK; |
208 |
return r; |
177 |
} |
209 |
} |
178 |
|
210 |
|
179 |
static int parse_challenge(const sasl_utils_t *utils, |
211 |
static int parse_challenge(const sasl_utils_t *utils, |
Lines 693-699
static int strptrcasecmp(const void *arg1, const void *arg2)
Link Here
|
693 |
|
725 |
|
694 |
/* Convert the 6 words into binary data */ |
726 |
/* Convert the 6 words into binary data */ |
695 |
static int word2bin(const sasl_utils_t *utils, |
727 |
static int word2bin(const sasl_utils_t *utils, |
696 |
char *words, unsigned char *bin, const EVP_MD *md) |
728 |
char *words, unsigned char *bin, const EVP_MD *md, |
|
|
729 |
EVP_MD_CTX *mdctx) |
697 |
{ |
730 |
{ |
698 |
int i, j; |
731 |
int i, j; |
699 |
char *c, *word, buf[OTP_RESPONSE_MAX+1]; |
732 |
char *c, *word, buf[OTP_RESPONSE_MAX+1]; |
Lines 752-764
static int word2bin(const sasl_utils_t *utils,
Link Here
|
752 |
|
785 |
|
753 |
/* alternate dictionary */ |
786 |
/* alternate dictionary */ |
754 |
if (alt_dict) { |
787 |
if (alt_dict) { |
755 |
EVP_MD_CTX mdctx; |
|
|
756 |
char hash[EVP_MAX_MD_SIZE]; |
788 |
char hash[EVP_MAX_MD_SIZE]; |
757 |
int hashlen; |
789 |
int hashlen; |
758 |
|
790 |
|
759 |
EVP_DigestInit(&mdctx, md); |
791 |
EVP_DigestInit(mdctx, md); |
760 |
EVP_DigestUpdate(&mdctx, word, strlen(word)); |
792 |
EVP_DigestUpdate(mdctx, word, strlen(word)); |
761 |
EVP_DigestFinal(&mdctx, hash, &hashlen); |
793 |
EVP_DigestFinal(mdctx, hash, &hashlen); |
762 |
|
794 |
|
763 |
/* use lowest 11 bits */ |
795 |
/* use lowest 11 bits */ |
764 |
x = ((hash[hashlen-2] & 0x7) << 8) | hash[hashlen-1]; |
796 |
x = ((hash[hashlen-2] & 0x7) << 8) | hash[hashlen-1]; |
Lines 802-807
static int verify_response(server_context_t *text, const sasl_utils_t *utils,
Link Here
|
802 |
char *response) |
834 |
char *response) |
803 |
{ |
835 |
{ |
804 |
const EVP_MD *md; |
836 |
const EVP_MD *md; |
|
|
837 |
EVP_MD_CTX *mdctx = NULL; |
805 |
char *c; |
838 |
char *c; |
806 |
int do_init = 0; |
839 |
int do_init = 0; |
807 |
unsigned char cur_otp[OTP_HASH_SIZE], prev_otp[OTP_HASH_SIZE]; |
840 |
unsigned char cur_otp[OTP_HASH_SIZE], prev_otp[OTP_HASH_SIZE]; |
Lines 815-820
static int verify_response(server_context_t *text, const sasl_utils_t *utils,
Link Here
|
815 |
return SASL_FAIL; |
848 |
return SASL_FAIL; |
816 |
} |
849 |
} |
817 |
|
850 |
|
|
|
851 |
if ((mdctx = _plug_EVP_MD_CTX_new(utils)) == NULL) { |
852 |
SETERROR(utils, "cannot allocate MD CTX"); |
853 |
return SASL_NOMEM; |
854 |
} |
855 |
|
818 |
/* eat leading whitespace */ |
856 |
/* eat leading whitespace */ |
819 |
c = response; |
857 |
c = response; |
820 |
while (isspace((int) *c)) c++; |
858 |
while (isspace((int) *c)) c++; |
Lines 824-830
static int verify_response(server_context_t *text, const sasl_utils_t *utils,
Link Here
|
824 |
r = hex2bin(c+strlen(OTP_HEX_TYPE), cur_otp, OTP_HASH_SIZE); |
862 |
r = hex2bin(c+strlen(OTP_HEX_TYPE), cur_otp, OTP_HASH_SIZE); |
825 |
} |
863 |
} |
826 |
else if (!strncasecmp(c, OTP_WORD_TYPE, strlen(OTP_WORD_TYPE))) { |
864 |
else if (!strncasecmp(c, OTP_WORD_TYPE, strlen(OTP_WORD_TYPE))) { |
827 |
r = word2bin(utils, c+strlen(OTP_WORD_TYPE), cur_otp, md); |
865 |
r = word2bin(utils, c+strlen(OTP_WORD_TYPE), cur_otp, md, mdctx); |
828 |
} |
866 |
} |
829 |
else if (!strncasecmp(c, OTP_INIT_HEX_TYPE, |
867 |
else if (!strncasecmp(c, OTP_INIT_HEX_TYPE, |
830 |
strlen(OTP_INIT_HEX_TYPE))) { |
868 |
strlen(OTP_INIT_HEX_TYPE))) { |
Lines 834-840
static int verify_response(server_context_t *text, const sasl_utils_t *utils,
Link Here
|
834 |
else if (!strncasecmp(c, OTP_INIT_WORD_TYPE, |
872 |
else if (!strncasecmp(c, OTP_INIT_WORD_TYPE, |
835 |
strlen(OTP_INIT_WORD_TYPE))) { |
873 |
strlen(OTP_INIT_WORD_TYPE))) { |
836 |
do_init = 1; |
874 |
do_init = 1; |
837 |
r = word2bin(utils, c+strlen(OTP_INIT_WORD_TYPE), cur_otp, md); |
875 |
r = word2bin(utils, c+strlen(OTP_INIT_WORD_TYPE), cur_otp, md, mdctx); |
838 |
} |
876 |
} |
839 |
else { |
877 |
else { |
840 |
SETERROR(utils, "unknown OTP extended response type"); |
878 |
SETERROR(utils, "unknown OTP extended response type"); |
Lines 843-856
static int verify_response(server_context_t *text, const sasl_utils_t *utils,
Link Here
|
843 |
} |
881 |
} |
844 |
else { |
882 |
else { |
845 |
/* standard response, try word first, and then hex */ |
883 |
/* standard response, try word first, and then hex */ |
846 |
r = word2bin(utils, c, cur_otp, md); |
884 |
r = word2bin(utils, c, cur_otp, md, mdctx); |
847 |
if (r != SASL_OK) |
885 |
if (r != SASL_OK) |
848 |
r = hex2bin(c, cur_otp, OTP_HASH_SIZE); |
886 |
r = hex2bin(c, cur_otp, OTP_HASH_SIZE); |
849 |
} |
887 |
} |
850 |
|
888 |
|
851 |
if (r == SASL_OK) { |
889 |
if (r == SASL_OK) { |
852 |
/* do one more hash (previous otp) and compare to stored otp */ |
890 |
/* do one more hash (previous otp) and compare to stored otp */ |
853 |
otp_hash(md, cur_otp, OTP_HASH_SIZE, prev_otp, text->alg->swab); |
891 |
otp_hash(md, cur_otp, OTP_HASH_SIZE, prev_otp, text->alg->swab, mdctx); |
854 |
|
892 |
|
855 |
if (!memcmp(prev_otp, text->otp, OTP_HASH_SIZE)) { |
893 |
if (!memcmp(prev_otp, text->otp, OTP_HASH_SIZE)) { |
856 |
/* update the secret with this seq/otp */ |
894 |
/* update the secret with this seq/otp */ |
Lines 879-901
static int verify_response(server_context_t *text, const sasl_utils_t *utils,
Link Here
|
879 |
*new_resp++ = '\0'; |
917 |
*new_resp++ = '\0'; |
880 |
} |
918 |
} |
881 |
|
919 |
|
882 |
if (!(new_chal && new_resp)) |
920 |
if (!(new_chal && new_resp)) { |
883 |
return SASL_BADAUTH; |
921 |
r = SASL_BADAUTH; |
|
|
922 |
goto done; |
923 |
} |
884 |
|
924 |
|
885 |
if ((r = parse_challenge(utils, new_chal, &alg, &seq, seed, 1)) |
925 |
if ((r = parse_challenge(utils, new_chal, &alg, &seq, seed, 1)) |
886 |
!= SASL_OK) { |
926 |
!= SASL_OK) { |
887 |
return r; |
927 |
goto done; |
888 |
} |
928 |
} |
889 |
|
929 |
|
890 |
if (seq < 1 || !strcasecmp(seed, text->seed)) |
930 |
if (seq < 1 || !strcasecmp(seed, text->seed)) { |
891 |
return SASL_BADAUTH; |
931 |
r = SASL_BADAUTH; |
|
|
932 |
goto done; |
933 |
} |
892 |
|
934 |
|
893 |
/* find the MDA */ |
935 |
/* find the MDA */ |
894 |
if (!(md = EVP_get_digestbyname(alg->evp_name))) { |
936 |
if (!(md = EVP_get_digestbyname(alg->evp_name))) { |
895 |
utils->seterror(utils->conn, 0, |
937 |
utils->seterror(utils->conn, 0, |
896 |
"OTP algorithm %s is not available", |
938 |
"OTP algorithm %s is not available", |
897 |
alg->evp_name); |
939 |
alg->evp_name); |
898 |
return SASL_BADAUTH; |
940 |
r = SASL_BADAUTH; |
|
|
941 |
goto done; |
899 |
} |
942 |
} |
900 |
|
943 |
|
901 |
if (!strncasecmp(c, OTP_INIT_HEX_TYPE, strlen(OTP_INIT_HEX_TYPE))) { |
944 |
if (!strncasecmp(c, OTP_INIT_HEX_TYPE, strlen(OTP_INIT_HEX_TYPE))) { |
Lines 903-909
static int verify_response(server_context_t *text, const sasl_utils_t *utils,
Link Here
|
903 |
} |
946 |
} |
904 |
else if (!strncasecmp(c, OTP_INIT_WORD_TYPE, |
947 |
else if (!strncasecmp(c, OTP_INIT_WORD_TYPE, |
905 |
strlen(OTP_INIT_WORD_TYPE))) { |
948 |
strlen(OTP_INIT_WORD_TYPE))) { |
906 |
r = word2bin(utils, new_resp, new_otp, md); |
949 |
r = word2bin(utils, new_resp, new_otp, md, mdctx); |
907 |
} |
950 |
} |
908 |
|
951 |
|
909 |
if (r == SASL_OK) { |
952 |
if (r == SASL_OK) { |
Lines 914-920
static int verify_response(server_context_t *text, const sasl_utils_t *utils,
Link Here
|
914 |
memcpy(text->otp, new_otp, OTP_HASH_SIZE); |
957 |
memcpy(text->otp, new_otp, OTP_HASH_SIZE); |
915 |
} |
958 |
} |
916 |
} |
959 |
} |
917 |
|
960 |
|
|
|
961 |
done: |
962 |
if (mdctx) _plug_EVP_MD_CTX_free(mdctx, utils); |
963 |
|
918 |
return r; |
964 |
return r; |
919 |
} |
965 |
} |
920 |
|
966 |
|
Lines 1443-1450
int otp_server_plug_init(const sasl_utils_t *utils,
Link Here
|
1443 |
*pluglist = otp_server_plugins; |
1489 |
*pluglist = otp_server_plugins; |
1444 |
*plugcount = 1; |
1490 |
*plugcount = 1; |
1445 |
|
1491 |
|
|
|
1492 |
#if OPENSSL_VERSION_NUMBER < 0x10100000L |
1446 |
/* Add all digests */ |
1493 |
/* Add all digests */ |
1447 |
OpenSSL_add_all_digests(); |
1494 |
OpenSSL_add_all_digests(); |
|
|
1495 |
#endif |
1448 |
|
1496 |
|
1449 |
return SASL_OK; |
1497 |
return SASL_OK; |
1450 |
} |
1498 |
} |
Lines 1844-1851
int otp_client_plug_init(sasl_utils_t *utils,
Link Here
|
1844 |
*pluglist = otp_client_plugins; |
1892 |
*pluglist = otp_client_plugins; |
1845 |
*plugcount = 1; |
1893 |
*plugcount = 1; |
1846 |
|
1894 |
|
|
|
1895 |
#if OPENSSL_VERSION_NUMBER < 0x10100000L |
1847 |
/* Add all digests */ |
1896 |
/* Add all digests */ |
1848 |
OpenSSL_add_all_digests(); |
1897 |
OpenSSL_add_all_digests(); |
|
|
1898 |
#endif |
1849 |
|
1899 |
|
1850 |
return SASL_OK; |
1900 |
return SASL_OK; |
1851 |
} |
1901 |
} |
1852 |
-- a/saslauthd/lak.c |
1902 |
++ b/saslauthd/lak.c |
Lines 729-735
int lak_init(
Link Here
|
729 |
return rc; |
729 |
return rc; |
730 |
} |
730 |
} |
731 |
|
731 |
|
732 |
#ifdef HAVE_OPENSSL |
732 |
#if defined(HAVE_OPENSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L |
733 |
OpenSSL_add_all_digests(); |
733 |
OpenSSL_add_all_digests(); |
734 |
#endif |
734 |
#endif |
735 |
|
735 |
|