Ruby
2.1.3p242(2014-09-19revision47630)
Main Page
Modules
Data Structures
Files
File List
Globals
ext
openssl
ossl_hmac.c
Go to the documentation of this file.
1
/*
2
* $Id: ossl_hmac.c 42416 2013-08-06 23:32:42Z zzak $
3
* 'OpenSSL for Ruby' project
4
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
* All rights reserved.
6
*/
7
/*
8
* This program is licenced under the same licence as Ruby.
9
* (See the file 'LICENCE'.)
10
*/
11
#if !defined(OPENSSL_NO_HMAC)
12
13
#include "
ossl.h
"
14
15
#define MakeHMAC(obj, klass, ctx) \
16
(obj) = Data_Make_Struct((klass), HMAC_CTX, 0, ossl_hmac_free, (ctx))
17
#define GetHMAC(obj, ctx) do { \
18
Data_Get_Struct((obj), HMAC_CTX, (ctx)); \
19
if (!(ctx)) { \
20
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
21
} \
22
} while (0)
23
#define SafeGetHMAC(obj, ctx) do { \
24
OSSL_Check_Kind((obj), cHMAC); \
25
GetHMAC((obj), (ctx)); \
26
} while (0)
27
28
/*
29
* Classes
30
*/
31
VALUE
cHMAC
;
32
VALUE
eHMACError
;
33
34
/*
35
* Public
36
*/
37
38
/*
39
* Private
40
*/
41
static
void
42
ossl_hmac_free
(HMAC_CTX *ctx)
43
{
44
HMAC_CTX_cleanup
(ctx);
45
ruby_xfree
(ctx);
46
}
47
48
static
VALUE
49
ossl_hmac_alloc
(
VALUE
klass)
50
{
51
HMAC_CTX *ctx;
52
VALUE
obj;
53
54
MakeHMAC
(obj, klass, ctx);
55
HMAC_CTX_init
(ctx);
56
57
return
obj;
58
}
59
60
61
/*
62
* call-seq:
63
* HMAC.new(key, digest) -> hmac
64
*
65
* Returns an instance of OpenSSL::HMAC set with the key and digest
66
* algorithm to be used. The instance represents the initial state of
67
* the message authentication code before any data has been processed.
68
* To process data with it, use the instance method #update with your
69
* data as an argument.
70
*
71
* === Example
72
*
73
* key = 'key'
74
* digest = OpenSSL::Digest.new('sha1')
75
* instance = OpenSSL::HMAC.new(key, digest)
76
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
77
* instance.class
78
* #=> OpenSSL::HMAC
79
*
80
* === A note about comparisons
81
*
82
* Two instances won't be equal when they're compared, even if they have the
83
* same value. Use #to_s or #hexdigest to return the authentication code that
84
* the instance represents. For example:
85
*
86
* other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
87
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
88
* instance
89
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
90
* instance == other_instance
91
* #=> false
92
* instance.to_s == other_instance.to_s
93
* #=> true
94
*
95
*/
96
static
VALUE
97
ossl_hmac_initialize
(
VALUE
self
,
VALUE
key
,
VALUE
digest)
98
{
99
HMAC_CTX *ctx;
100
101
StringValue
(key);
102
GetHMAC
(
self
, ctx);
103
HMAC_Init(ctx,
RSTRING_PTR
(key),
RSTRING_LENINT
(key),
104
GetDigestPtr
(digest));
105
106
return
self
;
107
}
108
109
static
VALUE
110
ossl_hmac_copy
(
VALUE
self
,
VALUE
other)
111
{
112
HMAC_CTX *ctx1, *ctx2;
113
114
rb_check_frozen
(
self
);
115
if
(
self
== other)
return
self
;
116
117
GetHMAC
(
self
, ctx1);
118
SafeGetHMAC
(other, ctx2);
119
120
HMAC_CTX_copy
(ctx1, ctx2);
121
return
self
;
122
}
123
124
/*
125
* call-seq:
126
* hmac.update(string) -> self
127
*
128
* Returns +self+ updated with the message to be authenticated.
129
* Can be called repeatedly with chunks of the message.
130
*
131
* === Example
132
*
133
* first_chunk = 'The quick brown fox jumps '
134
* second_chunk = 'over the lazy dog'
135
*
136
* instance.update(first_chunk)
137
* #=> 5b9a8038a65d571076d97fe783989e52278a492a
138
* instance.update(second_chunk)
139
* #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
140
*
141
*/
142
static
VALUE
143
ossl_hmac_update
(
VALUE
self
,
VALUE
data)
144
{
145
HMAC_CTX *ctx;
146
147
StringValue
(data);
148
GetHMAC
(
self
, ctx);
149
HMAC_Update(ctx, (
unsigned
char
*)
RSTRING_PTR
(data),
RSTRING_LEN
(data));
150
151
return
self
;
152
}
153
154
static
void
155
hmac_final
(HMAC_CTX *ctx,
unsigned
char
**
buf
,
unsigned
int
*buf_len)
156
{
157
HMAC_CTX
final
;
158
159
HMAC_CTX_copy
(&
final
, ctx);
160
if
(!(*buf = OPENSSL_malloc(HMAC_size(&
final
)))) {
161
HMAC_CTX_cleanup
(&
final
);
162
OSSL_Debug
(
"Allocating %d mem"
, HMAC_size(&
final
));
163
ossl_raise
(
eHMACError
,
"Cannot allocate memory for hmac"
);
164
}
165
HMAC_Final(&
final
, *buf, buf_len);
166
HMAC_CTX_cleanup
(&
final
);
167
}
168
169
/*
170
* call-seq:
171
* hmac.digest -> string
172
*
173
* Returns the authentication code an instance represents as a binary string.
174
*
175
* === Example
176
*
177
* instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
178
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
179
* instance.digest
180
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
181
*
182
*/
183
static
VALUE
184
ossl_hmac_digest
(
VALUE
self
)
185
{
186
HMAC_CTX *ctx;
187
unsigned
char
*
buf
;
188
unsigned
int
buf_len;
189
VALUE
digest;
190
191
GetHMAC
(
self
, ctx);
192
hmac_final
(ctx, &buf, &buf_len);
193
digest =
ossl_buf2str
((
char
*)buf, buf_len);
194
195
return
digest;
196
}
197
198
/*
199
* call-seq:
200
* hmac.hexdigest -> string
201
*
202
* Returns the authentication code an instance represents as a hex-encoded
203
* string.
204
*
205
*/
206
static
VALUE
207
ossl_hmac_hexdigest
(
VALUE
self
)
208
{
209
HMAC_CTX *ctx;
210
unsigned
char
*
buf
;
211
char
*hexbuf;
212
unsigned
int
buf_len;
213
VALUE
hexdigest;
214
215
GetHMAC
(
self
, ctx);
216
hmac_final
(ctx, &buf, &buf_len);
217
if
(
string2hex
(buf, buf_len, &hexbuf,
NULL
) != 2 * (
int
)buf_len) {
218
OPENSSL_free(buf);
219
ossl_raise
(
eHMACError
,
"Memory alloc error"
);
220
}
221
OPENSSL_free(buf);
222
hexdigest =
ossl_buf2str
(hexbuf, 2 * buf_len);
223
224
return
hexdigest;
225
}
226
227
/*
228
* call-seq:
229
* hmac.reset -> self
230
*
231
* Returns +self+ as it was when it was first initialized, with all processed
232
* data cleared from it.
233
*
234
* === Example
235
*
236
* data = "The quick brown fox jumps over the lazy dog"
237
* instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
238
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
239
*
240
* instance.update(data)
241
* #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
242
* instance.reset
243
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
244
*
245
*/
246
static
VALUE
247
ossl_hmac_reset
(
VALUE
self
)
248
{
249
HMAC_CTX *ctx;
250
251
GetHMAC
(
self
, ctx);
252
HMAC_Init(ctx,
NULL
, 0,
NULL
);
253
254
return
self
;
255
}
256
257
/*
258
* call-seq:
259
* HMAC.digest(digest, key, data) -> aString
260
*
261
* Returns the authentication code as a binary string. The +digest+ parameter
262
* must be an instance of OpenSSL::Digest.
263
*
264
* === Example
265
*
266
* key = 'key'
267
* data = 'The quick brown fox jumps over the lazy dog'
268
* digest = OpenSSL::Digest.new('sha1')
269
*
270
* hmac = OpenSSL::HMAC.digest(digest, key, data)
271
* #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
272
*
273
*/
274
static
VALUE
275
ossl_hmac_s_digest
(
VALUE
klass,
VALUE
digest,
VALUE
key
,
VALUE
data)
276
{
277
unsigned
char
*
buf
;
278
unsigned
int
buf_len;
279
280
StringValue
(key);
281
StringValue
(data);
282
buf = HMAC(
GetDigestPtr
(digest),
RSTRING_PTR
(key),
RSTRING_LENINT
(key),
283
(
unsigned
char
*)
RSTRING_PTR
(data),
RSTRING_LEN
(data),
NULL
, &buf_len);
284
285
return
rb_str_new
((
const
char
*)buf, buf_len);
286
}
287
288
/*
289
* call-seq:
290
* HMAC.hexdigest(digest, key, data) -> aString
291
*
292
* Returns the authentication code as a hex-encoded string. The +digest+
293
* parameter must be an instance of OpenSSL::Digest.
294
*
295
* === Example
296
*
297
* key = 'key'
298
* data = 'The quick brown fox jumps over the lazy dog'
299
* digest = OpenSSL::Digest.new('sha1')
300
*
301
* hmac = OpenSSL::HMAC.hexdigest(digest, key, data)
302
* #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
303
*
304
*/
305
static
VALUE
306
ossl_hmac_s_hexdigest
(
VALUE
klass,
VALUE
digest,
VALUE
key
,
VALUE
data)
307
{
308
unsigned
char
*
buf
;
309
char
*hexbuf;
310
unsigned
int
buf_len;
311
VALUE
hexdigest;
312
313
StringValue
(key);
314
StringValue
(data);
315
316
buf = HMAC(
GetDigestPtr
(digest),
RSTRING_PTR
(key),
RSTRING_LENINT
(key),
317
(
unsigned
char
*)
RSTRING_PTR
(data),
RSTRING_LEN
(data),
NULL
, &buf_len);
318
if
(
string2hex
(buf, buf_len, &hexbuf,
NULL
) != 2 * (
int
)buf_len) {
319
ossl_raise
(
eHMACError
,
"Cannot convert buf to hexbuf"
);
320
}
321
hexdigest =
ossl_buf2str
(hexbuf, 2 * buf_len);
322
323
return
hexdigest;
324
}
325
326
/*
327
* INIT
328
*/
329
void
330
Init_ossl_hmac
()
331
{
332
#if 0
333
/* :nodoc: */
334
mOSSL
=
rb_define_module
(
"OpenSSL"
);
/* let rdoc know about mOSSL */
335
#endif
336
337
eHMACError
=
rb_define_class_under
(
mOSSL
,
"HMACError"
,
eOSSLError
);
338
339
cHMAC
=
rb_define_class_under
(
mOSSL
,
"HMAC"
,
rb_cObject
);
340
341
rb_define_alloc_func
(
cHMAC
,
ossl_hmac_alloc
);
342
rb_define_singleton_method
(
cHMAC
,
"digest"
,
ossl_hmac_s_digest
, 3);
343
rb_define_singleton_method
(
cHMAC
,
"hexdigest"
,
ossl_hmac_s_hexdigest
, 3);
344
345
rb_define_method
(
cHMAC
,
"initialize"
,
ossl_hmac_initialize
, 2);
346
rb_define_copy_func
(
cHMAC
,
ossl_hmac_copy
);
347
348
rb_define_method
(
cHMAC
,
"reset"
,
ossl_hmac_reset
, 0);
349
rb_define_method
(
cHMAC
,
"update"
,
ossl_hmac_update
, 1);
350
rb_define_alias
(
cHMAC
,
"<<"
,
"update"
);
351
rb_define_method
(
cHMAC
,
"digest"
,
ossl_hmac_digest
, 0);
352
rb_define_method
(
cHMAC
,
"hexdigest"
,
ossl_hmac_hexdigest
, 0);
353
rb_define_alias
(
cHMAC
,
"inspect"
,
"hexdigest"
);
354
rb_define_alias
(
cHMAC
,
"to_s"
,
"hexdigest"
);
355
}
356
357
#else
/* NO_HMAC */
358
# warning >>> OpenSSL is compiled without HMAC support <<<
359
void
360
Init_ossl_hmac
()
361
{
362
rb_warning
(
"HMAC will NOT be avaible: OpenSSL is compiled without HMAC."
);
363
}
364
#endif
/* NO_HMAC */
365
Generated on Mon Sep 22 2014 11:05:25 for Ruby by
1.8.2