Skip to content

Commit cd41433

Browse files
committed
mod_auth_digest: use apr_crypto_equals
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1933355 13f79535-47bb-0310-9956-ffa450edef68
1 parent 73e7baa commit cd41433

2 files changed

Lines changed: 20 additions & 29 deletions

File tree

configure.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,10 +444,10 @@ if test "${apu_found}" = "yes"; then
444444
# we need to add the APR includes to CPPFLAGS
445445
apu_ckver_CPPFLAGS="$CPPFLAGS"
446446
CPPFLAGS="$CPPFLAGS `$apr_config --includes`"
447-
APACHE_CHECK_APxVER([apu], 1, 3)
447+
APACHE_CHECK_APxVER([apu], 1, 6)
448448
CPPFLAGS="$apu_ckver_CPPFLAGS"
449449
else
450-
APACHE_CHECK_APxVER([apu], 1, 3)
450+
APACHE_CHECK_APxVER([apu], 1, 6)
451451
fi
452452
fi
453453

modules/aaa/mod_auth_digest.c

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#include "apr_shm.h"
7474
#include "apr_rmm.h"
7575
#include "ap_provider.h"
76+
#include "apr_crypto.h" /* for apr_crypto_equals */
7677

7778
#include "mod_auth.h"
7879

@@ -99,10 +100,17 @@ typedef struct digest_config_struct {
99100
#define DFLT_NONCE_LIFE apr_time_from_sec(300)
100101
#define NEXTNONCE_DELTA apr_time_from_sec(30)
101102

102-
103+
/* The server nonce has fixed length and is the concatenation of:
104+
* base64(apr_time_t timestamp) + hex(SHA1(realm+time[+opaque])) */
103105
#define NONCE_TIME_LEN (((sizeof(apr_time_t)+2)/3)*4)
104106
#define NONCE_HASH_LEN (2*APR_SHA1_DIGESTSIZE)
105107
#define NONCE_LEN (int )(NONCE_TIME_LEN + NONCE_HASH_LEN)
108+
/* Evaluates to true if nonce string is valid. Since the time part of
109+
* the nonce is a base64 encoding of an apr_time_t (8 bytes), it
110+
* must end with a '='. */
111+
#define VALID_NONCE(n_) ((n_) && strlen((n_)) == NONCE_LEN && (n_)[NONCE_TIME_LEN - 1] == '=')
112+
113+
#define MD5_DIGEST_LEN (2*APR_MD5_DIGESTSIZE) /* ignoring trailing \0 */
106114

107115
#define SECRET_LEN 20
108116
#define RETAINED_DATA_ID "mod_auth_digest"
@@ -1013,8 +1021,9 @@ static int get_digest_rec(request_rec *r, digest_header_rec *resp)
10131021
resp->nonce_count = apr_pstrdup(r->pool, value);
10141022
}
10151023

1016-
if (!resp->username || !resp->realm || !resp->nonce || !resp->uri
1017-
|| !resp->digest
1024+
if (!resp->username || !resp->realm || !resp->uri
1025+
|| !VALID_NONCE(resp->nonce)
1026+
|| !resp->digest || strlen(resp->digest) != MD5_DIGEST_LEN
10181027
|| (resp->message_qop && (!resp->cnonce || !resp->nonce_count))) {
10191028
resp->auth_hdr_sts = INVALID;
10201029
return !OK;
@@ -1066,14 +1075,9 @@ static int parse_hdr_and_update_nc(request_rec *r)
10661075
}
10671076

10681077

1069-
/*
1070-
* Nonce generation code
1071-
*/
1072-
1073-
/* The hash part of the nonce is a SHA-1 hash of the time, realm, server host
1074-
* and port, opaque, and our secret.
1075-
*/
1076-
static void gen_nonce_hash(char *hash, const char *timestr, const char *opaque,
1078+
/* Writes the hash part of the server nonce to hash, which must be of
1079+
* minimum size (NONCE_HASH_LEN+1). */
1080+
static void gen_nonce_hash(char hash[NONCE_HASH_LEN+1], const char *timestr, const char *opaque,
10771081
const server_rec *server,
10781082
const digest_config_rec *conf,
10791083
const char *realm)
@@ -1427,27 +1431,14 @@ static int check_nonce(request_rec *r, digest_header_rec *resp,
14271431
time_rec nonce_time;
14281432
char tmp, hash[NONCE_HASH_LEN+1];
14291433

1430-
/* Since the time part of the nonce is a base64 encoding of an
1431-
* apr_time_t (8 bytes), it should end with a '=', fail early otherwise.
1432-
*/
1433-
if (strlen(resp->nonce) != NONCE_LEN
1434-
|| resp->nonce[NONCE_TIME_LEN - 1] != '=') {
1435-
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01775)
1436-
"invalid nonce '%s' received - length is not %d "
1437-
"or time encoding is incorrect",
1438-
resp->nonce, NONCE_LEN);
1439-
note_digest_auth_failure(r, conf, resp, 1);
1440-
return HTTP_UNAUTHORIZED;
1441-
}
1442-
14431434
tmp = resp->nonce[NONCE_TIME_LEN];
14441435
resp->nonce[NONCE_TIME_LEN] = '\0';
14451436
apr_base64_decode_binary(nonce_time.arr, resp->nonce);
14461437
gen_nonce_hash(hash, resp->nonce, resp->opaque, r->server, conf, ap_auth_name(r));
14471438
resp->nonce[NONCE_TIME_LEN] = tmp;
14481439
resp->nonce_time = nonce_time.time;
14491440

1450-
if (strcmp(hash, resp->nonce+NONCE_TIME_LEN)) {
1441+
if (!apr_crypto_equals(hash, resp->nonce+NONCE_TIME_LEN, NONCE_HASH_LEN)) {
14511442
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01776)
14521443
"invalid nonce %s received - hash is not %s",
14531444
resp->nonce, hash);
@@ -1778,7 +1769,7 @@ static int authenticate_digest_user(request_rec *r)
17781769

17791770
if (resp->message_qop == NULL) {
17801771
/* old (rfc-2069) style digest */
1781-
if (strcmp(resp->digest, old_digest(r, resp))) {
1772+
if (!apr_crypto_equals(resp->digest, old_digest(r, resp), MD5_DIGEST_LEN)) {
17821773
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01792)
17831774
"user %s: password mismatch: %s", r->user,
17841775
r->uri);
@@ -1813,7 +1804,7 @@ static int authenticate_digest_user(request_rec *r)
18131804
/* we failed to allocate a client struct */
18141805
return HTTP_INTERNAL_SERVER_ERROR;
18151806
}
1816-
if (strcmp(resp->digest, exp_digest)) {
1807+
if (!apr_crypto_equals(resp->digest, exp_digest, MD5_DIGEST_LEN)) {
18171808
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01794)
18181809
"user %s: password mismatch: %s", r->user,
18191810
r->uri);

0 commit comments

Comments
 (0)