@@ -59,10 +59,60 @@ namespace experimental
59
59
#include < winternl.h>
60
60
#include < bcrypt.h>
61
61
62
- std::vector<unsigned char > oauth1_config::_hmac_sha1 (const utility::string_t &, const utility::string_t &)
63
- {
64
- // CodePlex #230
65
- return std::vector<unsigned char >();
62
+ std::vector<unsigned char > oauth1_config::_hmac_sha1 (const utility::string_t & key, const utility::string_t & data)
63
+ {
64
+ NTSTATUS status;
65
+ BCRYPT_ALG_HANDLE alg_handle = nullptr ;
66
+ BCRYPT_HASH_HANDLE hash_handle = nullptr ;
67
+
68
+ std::vector<unsigned char > hash;
69
+ DWORD hash_len = 0 ;
70
+ ULONG result_len = 0 ;
71
+
72
+ auto key_c = conversions::utf16_to_utf8 (key);
73
+ auto data_c = conversions::utf16_to_utf8 (data);
74
+
75
+ status = BCryptOpenAlgorithmProvider (&alg_handle, BCRYPT_SHA1_ALGORITHM, nullptr , BCRYPT_ALG_HANDLE_HMAC_FLAG);
76
+ if (!NT_SUCCESS (status))
77
+ {
78
+ goto cleanup;
79
+ }
80
+ status = BCryptGetProperty (alg_handle, BCRYPT_HASH_LENGTH, (PBYTE) &hash_len, sizeof (hash_len), &result_len, 0 );
81
+ if (!NT_SUCCESS (status))
82
+ {
83
+ goto cleanup;
84
+ }
85
+ hash.resize (hash_len);
86
+
87
+ status = BCryptCreateHash (alg_handle, &hash_handle, nullptr , 0 , (PBYTE) key_c.c_str (), (ULONG) key_c.length (), 0 );
88
+ if (!NT_SUCCESS (status))
89
+ {
90
+ goto cleanup;
91
+ }
92
+ status = BCryptHashData (hash_handle, (PBYTE) data_c.c_str (), (ULONG) data_c.length (), 0 );
93
+ if (!NT_SUCCESS (status))
94
+ {
95
+ goto cleanup;
96
+ }
97
+ status = BCryptFinishHash (hash_handle, hash.data (), hash_len, 0 );
98
+ if (!NT_SUCCESS (status))
99
+ {
100
+ goto cleanup;
101
+ }
102
+
103
+ return hash;
104
+
105
+ cleanup:
106
+ if (hash_handle)
107
+ {
108
+ BCryptDestroyHash (hash_handle);
109
+ }
110
+ if (alg_handle)
111
+ {
112
+ BCryptCloseAlgorithmProvider (alg_handle, 0 );
113
+ }
114
+
115
+ return hash;
66
116
}
67
117
68
118
#elif defined(_MS_WINDOWS) && defined(__cplusplus_winrt) // Windows RT
@@ -71,20 +121,37 @@ using namespace Windows::Security::Cryptography;
71
121
using namespace Windows ::Security::Cryptography::Core;
72
122
using namespace Windows ::Storage::Streams;
73
123
74
- std::vector<unsigned char > oauth1_config::_hmac_sha1 (const utility::string_t &, const utility::string_t &)
75
- {
76
- // CodePlex #230
77
- return std::vector<unsigned char >();
124
+ std::vector<unsigned char > oauth1_config::_hmac_sha1 (const utility::string_t & key, const utility::string_t & data)
125
+ {
126
+ Platform::String^ data_str = ref new Platform::String (data.c_str ());
127
+ Platform::String^ key_str = ref new Platform::String (key.c_str ());
128
+
129
+ MacAlgorithmProvider^ HMACSha1Provider = MacAlgorithmProvider::OpenAlgorithm (MacAlgorithmNames::HmacSha1);
130
+ IBuffer^ content_buffer = CryptographicBuffer::ConvertStringToBinary (data_str, BinaryStringEncoding::Utf8);
131
+ IBuffer^ key_buffer = CryptographicBuffer::ConvertStringToBinary (key_str, BinaryStringEncoding::Utf8);
132
+
133
+ auto signature_key = HMACSha1Provider->CreateKey (key_buffer);
134
+ auto signed_buffer = CryptographicEngine::Sign (signature_key, content_buffer);
135
+
136
+ Platform::Array<unsigned char , 1 >^ arr;
137
+ CryptographicBuffer::CopyToByteArray (signed_buffer, &arr);
138
+ return std::vector<unsigned char >(arr->Data , arr->Data + arr->Length );
78
139
}
79
140
80
141
#else // Linux, Mac OS X
81
142
82
143
#include < openssl/hmac.h>
83
144
84
- std::vector<unsigned char > oauth1_config::_hmac_sha1 (const utility::string_t &, const utility::string_t &)
85
- {
86
- // CodePlex #230
87
- return std::vector<unsigned char >();
145
+ std::vector<unsigned char > oauth1_config::_hmac_sha1 (const utility::string_t & key, const utility::string_t & data)
146
+ {
147
+ unsigned char digest[HMAC_MAX_MD_CBLOCK];
148
+ unsigned int digest_len = 0 ;
149
+
150
+ HMAC (EVP_sha1 (), key.c_str (), static_cast <int >(key.length ()),
151
+ (const unsigned char *) data.c_str (), data.length (),
152
+ digest, &digest_len);
153
+
154
+ return std::vector<unsigned char >(digest, digest + digest_len);
88
155
}
89
156
90
157
#endif
0 commit comments