소스 검색

auth: support for password hasing with SHA512

Daniel-Constantin Mierla 6 달 전
부모
커밋
f72ed8c5d7
3개의 변경된 파일163개의 추가작업 그리고 1개의 파일을 삭제
  1. 8 1
      src/modules/auth/auth_mod.c
  2. 117 0
      src/modules/auth/rfc2617_sha256.c
  3. 38 0
      src/modules/auth/rfc2617_sha256.h

+ 8 - 1
src/modules/auth/auth_mod.c

@@ -140,10 +140,12 @@ str auth_algorithm = {"", 0};
 
 #define AUTH_ALG_MD5_IDX 0
 #define AUTH_ALG_SHA256_IDX 1
+#define AUTH_ALG_SHA512_IDX 2
 /* clang-format off */
 static str auth_algorithm_list[] = {
 	{"MD5", 3},
 	{"SHA-256", 7},
+	{"SHA-512", 7},
 	{NULL, 0}
 };
 /* clang-format on */
@@ -517,9 +519,14 @@ static int ki_auth_algorithm(sip_msg_t *msg, str *alg)
 		hash_hex_len = HASHHEXLEN_SHA256;
 		calc_HA1 = calc_HA1_sha256;
 		calc_response = calc_response_sha256;
+	} else if(strcmp(auth_algorithm.s, "SHA-512") == 0) {
+		auth_algorithm = auth_algorithm_list[AUTH_ALG_SHA512_IDX];
+		hash_hex_len = HASHHEXLEN_SHA512;
+		calc_HA1 = calc_HA1_sha512;
+		calc_response = calc_response_sha512;
 	} else {
 		LM_ERR("Invalid algorithm provided."
-			   " Possible values are \"\", \"MD5\" or \"SHA-256\"\n");
+			   " Possible values are 'MD5', 'SHA-256' or 'SHA-512'\n");
 		return -1;
 	}
 

+ 117 - 0
src/modules/auth/rfc2617_sha256.c

@@ -150,3 +150,120 @@ void calc_response_sha256(HASHHEX_SHA256 _ha1, /* H(A1) */
 	sr_SHA256_Final(RespHash, &Sha256Ctx);
 	cvt_hex_sha256(RespHash, _response);
 }
+
+inline void cvt_hex_sha512(HASH_SHA512 _b, HASHHEX_SHA512 _h)
+{
+	unsigned short i;
+	unsigned char j;
+
+	for(i = 0; i < HASHLEN_SHA512; i++) {
+		j = (_b[i] >> 4) & 0xf;
+		if(j <= 9) {
+			_h[i * 2] = (j + '0');
+		} else {
+			_h[i * 2] = (j + 'a' - 10);
+		}
+
+		j = _b[i] & 0xf;
+
+		if(j <= 9) {
+			_h[i * 2 + 1] = (j + '0');
+		} else {
+			_h[i * 2 + 1] = (j + 'a' - 10);
+		}
+	};
+
+	_h[HASHHEXLEN_SHA512] = '\0';
+}
+
+/* Cast to unsigned values and forward to sr_SHA512_Update */
+static inline void SHA512_Update(SHA512_CTX *context, char *data, int len)
+{
+	sr_SHA512_Update(context, (unsigned char *)data, (unsigned int)len);
+}
+
+/*
+ * calculate H(A1) as per spec
+ */
+void calc_HA1_sha512(ha_alg_t _alg, str *_username, str *_realm, str *_password,
+		str *_nonce, str *_cnonce, HASHHEX_SHA512 _sess_key)
+{
+	SHA512_CTX Sha512Ctx;
+	HASH_SHA512 HA1;
+
+	sr_SHA512_Init(&Sha512Ctx);
+	SHA512_Update(&Sha512Ctx, _username->s, _username->len);
+	SHA512_Update(&Sha512Ctx, ":", 1);
+	SHA512_Update(&Sha512Ctx, _realm->s, _realm->len);
+	SHA512_Update(&Sha512Ctx, ":", 1);
+	SHA512_Update(&Sha512Ctx, _password->s, _password->len);
+	sr_SHA512_Final(HA1, &Sha512Ctx);
+
+	if(_alg == HA_MD5_SESS) {
+		sr_SHA512_Init(&Sha512Ctx);
+		sr_SHA512_Update(&Sha512Ctx, HA1, HASHLEN_SHA512);
+		SHA512_Update(&Sha512Ctx, ":", 1);
+		SHA512_Update(&Sha512Ctx, _nonce->s, _nonce->len);
+		SHA512_Update(&Sha512Ctx, ":", 1);
+		SHA512_Update(&Sha512Ctx, _cnonce->s, _cnonce->len);
+		sr_SHA512_Final(HA1, &Sha512Ctx);
+	};
+
+	cvt_hex_sha512(HA1, _sess_key);
+}
+
+
+/*
+ * calculate request-digest/response-digest as per HTTP Digest spec
+ */
+void calc_response_sha512(HASHHEX_SHA512 _ha1, /* H(A1) */
+		str *_nonce,						   /* nonce from server */
+		str *_nc,							   /* 8 hex digits */
+		str *_cnonce,						   /* client nonce */
+		str *_qop,				  /* qop-value: "", "auth", "auth-int" */
+		int _auth_int,			  /* 1 if auth-int is used */
+		str *_method,			  /* method from the request */
+		str *_uri,				  /* requested URL */
+		HASHHEX_SHA512 _hentity,  /* H(entity body) if qop="auth-int" */
+		HASHHEX_SHA512 _response) /* request-digest or response-digest */
+{
+	SHA512_CTX Sha512Ctx;
+	HASH_SHA512 HA2;
+	HASH_SHA512 RespHash;
+	HASHHEX_SHA512 HA2Hex;
+
+	/* calculate H(A2) */
+	sr_SHA512_Init(&Sha512Ctx);
+	if(_method) {
+		SHA512_Update(&Sha512Ctx, _method->s, _method->len);
+	}
+	SHA512_Update(&Sha512Ctx, ":", 1);
+	SHA512_Update(&Sha512Ctx, _uri->s, _uri->len);
+
+	if(_auth_int) {
+		SHA512_Update(&Sha512Ctx, ":", 1);
+		SHA512_Update(&Sha512Ctx, _hentity, HASHHEXLEN_SHA512);
+	};
+
+	sr_SHA512_Final(HA2, &Sha512Ctx);
+	cvt_hex_sha512(HA2, HA2Hex);
+
+	/* calculate response */
+	sr_SHA512_Init(&Sha512Ctx);
+	SHA512_Update(&Sha512Ctx, _ha1, HASHHEXLEN_SHA512);
+	SHA512_Update(&Sha512Ctx, ":", 1);
+	SHA512_Update(&Sha512Ctx, _nonce->s, _nonce->len);
+	SHA512_Update(&Sha512Ctx, ":", 1);
+
+	if(_qop->len) {
+		SHA512_Update(&Sha512Ctx, _nc->s, _nc->len);
+		SHA512_Update(&Sha512Ctx, ":", 1);
+		SHA512_Update(&Sha512Ctx, _cnonce->s, _cnonce->len);
+		SHA512_Update(&Sha512Ctx, ":", 1);
+		SHA512_Update(&Sha512Ctx, _qop->s, _qop->len);
+		SHA512_Update(&Sha512Ctx, ":", 1);
+	};
+	SHA512_Update(&Sha512Ctx, HA2Hex, HASHHEXLEN_SHA512);
+	sr_SHA512_Final(RespHash, &Sha512Ctx);
+	cvt_hex_sha512(RespHash, _response);
+}

+ 38 - 0
src/modules/auth/rfc2617_sha256.h

@@ -40,12 +40,26 @@ typedef unsigned char HASH_SHA256[HASHLEN_SHA256];
 typedef char HASHHEX_SHA256[HASHHEXLEN_SHA256 + 1];
 
 
+#define HASHLEN_SHA512 64
+typedef unsigned char HASH_SHA512[HASHLEN_SHA512];
+
+
+#define HASHHEXLEN_SHA512 128
+typedef char HASHHEX_SHA512[HASHHEXLEN_SHA512 + 1];
+
+
 /*
  * Convert to hex form
  */
 void cvt_hex_sha256(HASH_SHA256 Bin, HASHHEX_SHA256 Hex);
 
 
+/*
+ * Convert to hex form
+ */
+void cvt_hex_sha512(HASH_SHA512 Bin, HASHHEX_SHA512 Hex);
+
+
 /*
  * calculate H(A1) as per HTTP Digest spec
  */
@@ -70,4 +84,28 @@ void calc_response_sha256(HASHHEX_SHA256 _ha1, /* H(A1) */
 		HASHHEX_SHA256 _hentity,   /* H(entity body) if qop="auth-int" */
 		HASHHEX_SHA256 _response); /* request-digest or response-digest */
 
+/*
+ * calculate H(A1) as per HTTP Digest spec
+ */
+void calc_HA1_sha512(ha_alg_t _alg, /* Type of algorithm */
+		str *_username,				/* username */
+		str *_realm,				/* realm */
+		str *_password,				/* password */
+		str *_nonce,				/* nonce string */
+		str *_cnonce,				/* cnonce */
+		HASHHEX_SHA512 _sess_key);	/* Result will be stored here */
+
+
+/* calculate request-digest/response-digest as per HTTP Digest spec */
+void calc_response_sha512(HASHHEX_SHA512 _ha1, /* H(A1) */
+		str *_nonce,						   /* nonce from server */
+		str *_nc,							   /* 8 hex digits */
+		str *_cnonce,						   /* client nonce */
+		str *_qop,				   /* qop-value: "", "auth", "auth-int" */
+		int _auth_int,			   /* 1 if auth-int is used */
+		str *_method,			   /* method from the request */
+		str *_uri,				   /* requested URL */
+		HASHHEX_SHA512 _hentity,   /* H(entity body) if qop="auth-int" */
+		HASHHEX_SHA512 _response); /* request-digest or response-digest */
+
 #endif /* RFC2617_SHA256_H */