My Own Style

반응형
  • RFC 2069: HTTP Authentication: Basic and Digest Access Authentication
    • 초기버전
  • RFC 2617: HTTP Authentication: Basic and Digest Access Authentication
    • qop, nc(nonce count), cnonce(client nonce) 필드 추가
  • RFC 7616: HTTP Digest Access Authentication
    • SHA-512-256(-sess), SHA-256(-sess) Algorithm 추가

  • 요구사항 : HTTP 사용자 인증으로 Digest (RFC 7616) [SHA-2] 인증 방식을 사용해야 한다.
  • libcurl 은 서버에서 먼저 지원하는 목록의 algorithm 으로 인증을 진행하여 우선순위를 변경할 수 없는 단점을 가지고 있음
  • libcurl -  algorithm : sha-256, md5  를 서버에서 지원할 경우, sha-256 부터 인증 요청할 수 있도록 변경 진행, client 의 보안성을 향상시키기 위한 작업 (해당 library 가 spec out 은 아님)


  • Version: curl-7.60.0
  • diff 



$ git diff lib/http.c
diff --git a/lib/http.c b/lib/http.c
index ff1d681..4fce2f9 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -850,9 +850,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
 #endif
 #ifndef CURL_DISABLE_CRYPTO_AUTH
         if(checkprefix("Digest", auth)) {
-          if((authp->avail & CURLAUTH_DIGEST) != 0)
-            infof(data, "Ignoring duplicate digest auth header.\n");
-          else if(Curl_auth_is_digest_supported()) {
+          if(Curl_auth_is_digest_supported()) {
             CURLcode result;
             *availp |= CURLAUTH_DIGEST;
 
$ git diff lib/urldata.h
diff --git a/lib/urldata.h b/lib/urldata.h
index 7fae00f..7e4c5eb 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -296,6 +296,7 @@ struct digestdata {
   char *algorithm;
   int nc; /* nounce count */
   bool userhash;
+  bool used; /* Authentication Try */
 #endif
 };
 
$ git diff lib/vauth/digest.c
diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c
index 131d9da..a8d6bc2 100644
--- a/lib/vauth/digest.c
+++ b/lib/vauth/digest.c
@@ -505,6 +505,44 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
   return result;
 }
+static int _Curl_auth_digest_get_algorithm(const char *chlg, int *algorithm)
+{
+       int tmp = -1;
+       char algostr[DIGEST_MAX_CONTENT_LENGTH];
+       memset(algostr, 0x00, DIGEST_MAX_CONTENT_LENGTH);
+
+
+       if(!auth_digest_get_key_value((char *) chlg, "algorithm=\"",
+                               algostr, sizeof(algostr), '\"')) {
+               return CURLE_BAD_CONTENT_ENCODING;
+       }
+
+       if(strcasecompare(algostr, "MD5-sess")) {
+               tmp = CURLDIGESTALGO_MD5SESS;
+       }
+       else if(strcasecompare(algostr, "MD5")) {
+               tmp = CURLDIGESTALGO_MD5;
+       }
+       else if(strcasecompare(algostr, "SHA-256")) {
+               tmp = CURLDIGESTALGO_SHA256;
+       }
+       else if(strcasecompare(algostr, "SHA-256-SESS")) {
+               tmp = CURLDIGESTALGO_SHA256SESS;
+       }
+       else if(strcasecompare(algostr, "SHA-512-256")) {
+               tmp = CURLDIGESTALGO_SHA512_256;
+       }
+       else if(strcasecompare(algostr, "SHA-512-256-SESS")) {
+               tmp = CURLDIGESTALGO_SHA512_256SESS;
+       }
+       else
+               return CURLE_BAD_CONTENT_ENCODING;
+
+       *algorithm = tmp;
+
+       return CURLE_OK;
+}
+
 /*
  * Curl_auth_decode_digest_http_message()
  *
@@ -527,8 +565,20 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
   char *token = NULL;
   char *tmp = NULL;
+  /* Check Algorithm */
+  if(digest->nonce) {
+    int algo = -1;
+
+       if(_Curl_auth_digest_get_algorithm(chlg, &algo))
+               return CURLE_BAD_CONTENT_ENCODING;
+
+       if(digest->algo > algo)
+               return CURLE_OK;
+  printf("@ %s:%d Auth info replace>\n", __FUNCTION__, __LINE__);
+  }
+
   /* If we already have received a nonce, keep that in mind */
-  if(digest->nonce)
+  if(digest->used)
     before = TRUE;
   /* Clean up any former leftovers and initialise to defaults */
@@ -749,10 +799,13 @@ static CURLcode _Curl_auth_create_digest_http_message(
     return CURLE_OUT_OF_MEMORY;
   CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
+  printf("@ %s:%d - ha1-hint(%s)\n", __FUNCTION__, __LINE__, hashthis);
   hash(hashbuf, hashthis);
   free(hashthis);
   convert_to_ascii(hashbuf, ha1);
+  printf("@ %s:%d - ha1-hash(%s)\n", __FUNCTION__, __LINE__, ha1);
+
   if(digest->algo == CURLDIGESTALGO_MD5SESS ||
      digest->algo == CURLDIGESTALGO_SHA256SESS ||
      digest->algo == CURLDIGESTALGO_SHA512_256SESS) {
@@ -801,8 +854,10 @@ static CURLcode _Curl_auth_create_digest_http_message(
   CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
   hash(hashbuf, hashthis);
+  printf("@ %s:%d - ha2-hint(%s)\n", __FUNCTION__, __LINE__, hashthis);
   free(hashthis);
   convert_to_ascii(hashbuf, ha2);
+  printf("@ %s:%d - ha2-hash(%s)\n", __FUNCTION__, __LINE__, ha2);
   if(digest->qop) {
     hashthis = (unsigned char *) aprintf("%s:%s:%08x:%s:%s:%s",
@@ -824,10 +879,13 @@ static CURLcode _Curl_auth_create_digest_http_message(
     return CURLE_OUT_OF_MEMORY;
   CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
+  printf("@ %s:%d - response-hint(%s)\n", __FUNCTION__, __LINE__, hashthis);
   hash(hashbuf, hashthis);
   free(hashthis);
   convert_to_ascii(hashbuf, request_digest);
+  printf("@ %s:%d - response-hash(%s)\n", __FUNCTION__, __LINE__, request_digest);
+
   /* For test case 64 (snooped from a Mozilla 1.3a request)
      Authorization: Digest username="testuser", realm="testrealm", \
@@ -918,6 +976,7 @@ static CURLcode _Curl_auth_create_digest_http_message(
   /* Return the output */
   *outptr = response;
   *outlen = strlen(response);
+  digest->used = TRUE;
   return CURLE_OK;
 }
  • 참고자료
  • Source
    • https://dxr.mozilla.org/mozilla-beta/source/netwerk/protocol/http/nsHttpDigestAuth.cpp
    • https://bugzilla.mozilla.org/attachment.cgi?id=8683095&action=diff
    • https://github.com/alisw/gsoap/blob/master/gsoap/plugin/httpda.c
    • https://github.com/B-Con/crypto-algorithms
    • https://gitlab.com/gnuwget/wget2/blob/master/libwget/http.c
  • Document
    • Wiki: Digest access authentication
      • https://en.wikipedia.org/wiki/Digest_access_authentication

 

반응형

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band