1 /*
2 * Copyright 2009-2017 Alibaba Cloud All rights reserved.
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 #include "HmacSha1Signer.h"
18 #if 0//def _WIN32
19 #include <windows.h>
20 #include <wincrypt.h>
21 #elif defined(USE_CRYPTO_MBEDTLS)
22 #include "mbedtls/compat-1.3.h"
23 #include "mbedtls/sha1.h"
24 #include "mbedtls/base64.h"
25 #include "mbedtls/md.h"
26 #else
27 #include <openssl/hmac.h>
28 #ifdef OPENSSL_IS_BORINGSSL
29 #include <openssl/base64.h>
30 #endif
31 #endif
32
33 using namespace AlibabaCloud::OSS;
34
HmacSha1Signer()35 HmacSha1Signer::HmacSha1Signer() :
36 Signer(HmacSha1, "HMAC-SHA1", "1.0")
37 {
38 }
39
~HmacSha1Signer()40 HmacSha1Signer::~HmacSha1Signer()
41 {
42 }
43
generate(const std::string & src,const std::string & secret) const44 std::string HmacSha1Signer::generate(const std::string & src, const std::string & secret) const
45 {
46 if (src.empty())
47 return std::string();
48
49 #if 0//def _WIN32
50 typedef struct _my_blob {
51 BLOBHEADER hdr;
52 DWORD dwKeySize;
53 BYTE rgbKeyData[];
54 }my_blob;
55
56 DWORD kbLen = sizeof(my_blob) + secret.size();
57 my_blob * kb = (my_blob *)LocalAlloc(LPTR, kbLen);
58 kb->hdr.bType = PLAINTEXTKEYBLOB;
59 kb->hdr.bVersion = CUR_BLOB_VERSION;
60 kb->hdr.reserved = 0;
61 kb->hdr.aiKeyAlg = CALG_RC2;
62 kb->dwKeySize = secret.size();
63 memcpy(&kb->rgbKeyData, secret.c_str(), secret.size());
64
65 HCRYPTPROV hProv = 0;
66 HCRYPTKEY hKey = 0;
67 HCRYPTHASH hHmacHash = 0;
68 BYTE pbHash[32];
69 DWORD dwDataLen = 32;
70 HMAC_INFO HmacInfo;
71 ZeroMemory(&HmacInfo, sizeof(HmacInfo));
72 HmacInfo.HashAlgid = CALG_SHA1;
73
74 CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET);
75 CryptImportKey(hProv, (BYTE*)kb, kbLen, 0, CRYPT_IPSEC_HMAC_KEY, &hKey);
76 CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHmacHash);
77 CryptSetHashParam(hHmacHash, HP_HMAC_INFO, (BYTE*)&HmacInfo, 0);
78 CryptHashData(hHmacHash, (BYTE*)(src.c_str()), src.size(), 0);
79 CryptGetHashParam(hHmacHash, HP_HASHVAL, pbHash, &dwDataLen, 0);
80
81 LocalFree(kb);
82 CryptDestroyHash(hHmacHash);
83 CryptDestroyKey(hKey);
84 CryptReleaseContext(hProv, 0);
85
86 DWORD dlen = 0;
87 CryptBinaryToString(pbHash, dwDataLen, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &dlen);
88 char* dest = new char[dlen];
89 CryptBinaryToString(pbHash, dwDataLen, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, dest, &dlen);
90
91 std::string ret = std::string(dest, dlen);
92 delete dest;
93 return ret;
94 #elif 0//defined(USE_CRYPTO_MBEDTLS)
95 unsigned char md[20];
96 unsigned int mdLen = 20;
97 size_t olen = 0;
98
99 mbedtls_sha1_context sha1_ctx;
100
101 mbedtls_sha1_init(&sha1_ctx);
102 mbedtls_sha1_starts(&sha1_ctx);
103 mbedtls_sha1_update(&sha1_ctx, reinterpret_cast<const unsigned char*>(secret.c_str()), secret.size());
104 mbedtls_sha1_update(&sha1_ctx, reinterpret_cast<const unsigned char*>(src.c_str()), src.size());
105 mbedtls_sha1_finish(&sha1_ctx, md);
106 mbedtls_sha1_free(&sha1_ctx);
107
108 char encodedData[100];
109 mbedtls_base64_encode((unsigned char*)encodedData, sizeof(encodedData), &olen, md, mdLen);
110
111 return encodedData;
112
113 #elif defined(USE_CRYPTO_MBEDTLS)
114 unsigned char md[20];
115 unsigned int mdLen = 20;
116 size_t olen = 0;
117 mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1),
118 reinterpret_cast<const unsigned char*>(secret.c_str()),static_cast<int>(secret.size()),
119 reinterpret_cast<const unsigned char*>(src.c_str()), src.size(),
120 (unsigned char *)md);
121 char encodedData[100];
122 mbedtls_base64_encode((unsigned char*)encodedData, sizeof(encodedData), &olen, md, mdLen);
123
124 return encodedData;
125 #else
126 unsigned char md[32];
127 unsigned int mdLen = 32;
128
129 if (HMAC(EVP_sha1(), secret.c_str(), static_cast<int>(secret.size()),
130 reinterpret_cast<const unsigned char*>(src.c_str()), src.size(),
131 md, &mdLen) == nullptr)
132 return std::string();
133
134 char encodedData[100];
135 EVP_EncodeBlock(reinterpret_cast<unsigned char*>(encodedData), md, mdLen);
136 return encodedData;
137 #endif
138
139 }