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 }