Skip to content

Commit b0e813d

Browse files
yangyaokaibai-charisu
yangyaokai
authored andcommitted
replace HMacSha256 impl
Change-Id: Ib4842dd3569d706ccc504b2f7714f6ab684b6103
1 parent df1b21f commit b0e813d

File tree

5 files changed

+113
-68
lines changed

5 files changed

+113
-68
lines changed

LICENSE

+5
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ Copyright: Copyright (c) 2020, NetEase Inc.
9191
Copyright (c) 2015 Baidu.com, Inc.
9292
License: Apache 2.0 (see LICENSE_APACHE)
9393

94+
Files: src/common/authenticator.cpp
95+
Copyright: Copyright (c) 2020, NetEase Inc.
96+
Copyright (c) 2016 Baidu, Inc.
97+
License: Apache 2.0 (see LICENSE_APACHE)
98+
9499
Files: src/common/hash.h
95100
Copyright: Copyright (c) 2020, NetEase Inc.
96101
Copyright (c) 2015, Baidu.com

src/common/authenticator.cpp

+64-62
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,59 @@
1919
* File Created: Monday, 1st April 2019 5:15:34 pm
2020
* Author: tongguangxun
2121
*/
22+
23+
// function HMacSha256() is copy from brpc project:
24+
//
25+
// Copyright (c) 2016 Baidu, Inc.
26+
//
27+
// Licensed under the Apache License, Version 2.0 (the "License");
28+
// you may not use this file except in compliance with the License.
29+
// You may obtain a copy of the License at
30+
//
31+
// http://www.apache.org/licenses/LICENSE-2.0
32+
//
33+
// Unless required by applicable law or agreed to in writing, software
34+
// distributed under the License is distributed on an "AS IS" BASIS,
35+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36+
// See the License for the specific language governing permissions and
37+
// limitations under the License.
38+
39+
// Authors: Ge,Jun ([email protected])
40+
// Jiashun Zhu ([email protected])
41+
2242
#ifdef OPENSSL_NO_SHA256
2343
#undef OPENSSL_NO_SHA256
2444
#endif
2545

46+
#include <glog/logging.h>
2647
#include <openssl/sha.h>
48+
#include <openssl/hmac.h>
2749

2850
#include <string.h>
2951

3052
#include "src/common/authenticator.h"
3153

54+
// Older openssl does not have EVP_sha256. To make the code always compile,
55+
// we mark the symbol as weak. If the runtime does not have the function,
56+
// handshaking will fallback to the simple one.
57+
extern "C" {
58+
const EVP_MD* __attribute__((weak)) EVP_sha256(void);
59+
}
60+
3261
namespace curve {
3362
namespace common {
63+
3464
std::string Authenticator::CalcString2Signature(const std::string& in,
3565
const std::string& secretKey) {
3666
std::string signature;
3767
unsigned char digest[BUFSIZ];
3868
memset(digest, 0x00, BUFSIZ);
3969

40-
HMacSha256((unsigned char*)in.c_str(), in.size(),
41-
(unsigned char*)secretKey.c_str(), secretKey.size(), digest);
42-
signature = Base64(digest, SHA256_DIGEST_LENGTH);
70+
int ret = HMacSha256((unsigned char*)secretKey.c_str(), secretKey.size(),
71+
(unsigned char*)in.c_str(), in.size(), digest);
72+
if (ret == 0) {
73+
signature = Base64(digest, SHA256_DIGEST_LENGTH);
74+
}
4375

4476
return signature;
4577
}
@@ -52,67 +84,37 @@ std::string Authenticator::GetString2Signature(uint64_t date,
5284
.append(owner);
5385
}
5486

55-
void Authenticator::HMacSha256(
56-
const unsigned char *text, /* pointer to data stream */
57-
int text_len, /* length of data stream */
58-
const unsigned char *key, /* pointer to authentication key */
59-
int key_len, /* length of authentication key */
60-
void *digest) {
61-
unsigned char k_ipad[65]; /* inner padding key XORd with ipad */
62-
unsigned char k_opad[65]; /* outer padding key XORd with opad */
63-
unsigned char tk[SHA256_DIGEST_LENGTH];
64-
unsigned char tk2[SHA256_DIGEST_LENGTH];
65-
unsigned char bufferIn[1024];
66-
unsigned char bufferOut[1024];
67-
int i;
68-
69-
/* if key is longer than 64 bytes reset it to key=sha256(key) */
70-
if (key_len > 64) {
71-
SHA256(key, key_len, tk);
72-
key = tk;
73-
key_len = SHA256_DIGEST_LENGTH;
87+
int Authenticator::HMacSha256(const void* key, int key_size,
88+
const void* data, int data_size,
89+
void* digest) {
90+
if (NULL == EVP_sha256) {
91+
LOG(ERROR) << "Fail to find EVP_sha256.";
92+
return -1;
7493
}
75-
76-
/*
77-
* the HMAC_SHA256 transform looks like:
78-
*
79-
* SHA256(K XOR opad, SHA256(K XOR ipad, text))
80-
*
81-
* where K is an n byte key
82-
* ipad is the byte 0x36 repeated 64 times
83-
* opad is the byte 0x5c repeated 64 times
84-
* and text is the data being protected
85-
*/
86-
87-
/* start out by storing key in pads */
88-
memset(k_ipad, 0, sizeof k_ipad);
89-
memset(k_opad, 0, sizeof k_opad);
90-
memcpy(k_ipad, key, key_len);
91-
memcpy(k_opad, key, key_len);
92-
93-
/* XOR key with ipad and opad values */
94-
for (i = 0; i < 64; i++) {
95-
k_ipad[i] ^= 0x36;
96-
k_opad[i] ^= 0x5c;
94+
unsigned int digest_size = 0;
95+
unsigned char* temp_digest = (unsigned char*)digest;
96+
if (key == NULL) {
97+
// NOTE: first parameter of EVP_Digest in older openssl is void*.
98+
if (EVP_Digest(const_cast<void*>(data), data_size, temp_digest,
99+
&digest_size, EVP_sha256(), NULL) < 0) {
100+
LOG(ERROR) << "Fail to EVP_Digest";
101+
return -1;
102+
}
103+
} else {
104+
// Note: following code uses HMAC_CTX previously which is ABI
105+
// inconsistent in different version of openssl.
106+
if (HMAC(EVP_sha256(), key, key_size,
107+
(const unsigned char*) data, data_size,
108+
temp_digest, &digest_size) == NULL) {
109+
LOG(ERROR) << "Fail to HMAC";
110+
return -1;
111+
}
97112
}
98-
99-
/*
100-
* perform inner SHA256
101-
*/
102-
memset(bufferIn, 0x00, 1024);
103-
memcpy(bufferIn, k_ipad, 64);
104-
memcpy(bufferIn + 64, text, text_len);
105-
106-
SHA256(bufferIn, 64 + text_len, tk2);
107-
108-
/*
109-
* perform outer SHA256
110-
*/
111-
memset(bufferOut, 0x00, 1024);
112-
memcpy(bufferOut, k_opad, 64);
113-
memcpy(bufferOut + 64, tk2, SHA256_DIGEST_LENGTH);
114-
115-
SHA256(bufferOut, 64 + SHA256_DIGEST_LENGTH, (unsigned char*)digest);
113+
if (digest_size != 32) {
114+
LOG(ERROR) << "digest_size=" << digest_size << " of sha256 is not 32";
115+
return -1;
116+
}
117+
return 0;
116118
}
117119

118120
std::string Authenticator::Base64(const unsigned char *src, size_t sz) {

src/common/authenticator.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,9 @@ class Authenticator {
5656
const std::string& secretKey);
5757

5858
private:
59-
static void HMacSha256(
60-
const unsigned char *text, /* pointer to data stream */
61-
int text_len, /* length of data stream */
62-
const unsigned char *key, /* pointer to authentication key */
63-
int key_len, /* length of authentication key */
64-
void *digest);
59+
static int HMacSha256(const void* key, int key_size,
60+
const void* data, int data_size,
61+
void* digest);
6562

6663
static std::string Base64(const unsigned char *src, size_t sz);
6764
};

test/common/BUILD

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ cc_test(
2424
],
2525
deps = [
2626
"//src/common:curve_common",
27+
"//src/common:curve_auth",
2728
"//src/common:curve_s3_adapter",
2829
"//src/common/concurrent:curve_concurrent",
2930
"@com_google_googletest//:gtest_main",

test/common/authenticator_test.cpp

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2020 NetEase Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* Project: curve
19+
* Created Date: Thursday November 29th 2018
20+
* Author: yangyaokai
21+
*/
22+
23+
#include <gtest/gtest.h>
24+
#include <string>
25+
26+
#include "src/common/authenticator.h"
27+
28+
namespace curve {
29+
namespace common {
30+
31+
TEST(AuthenticatorTEST, basic_test) {
32+
std::string key = "123456";
33+
std::string data = "/data/123";
34+
std::string sig = Authenticator::CalcString2Signature(data, key);
35+
std::string expect = "ZKNsnF9DXRxeb0+xTgFD2zLYkQnE6Sy/g2ebqWEAdlc=";
36+
ASSERT_STREQ(sig.c_str(), expect.c_str());
37+
}
38+
39+
} // namespace common
40+
} // namespace curve

0 commit comments

Comments
 (0)