Ruby  2.0.0p594(2014-10-27revision48167)
ossl_hmac.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl_hmac.c 32609 2011-07-22 04:11:38Z emboss $
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  */
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
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  */
66 static VALUE
68 {
69  HMAC_CTX *ctx;
70 
71  StringValue(key);
72  GetHMAC(self, ctx);
73  HMAC_Init(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
74  GetDigestPtr(digest));
75 
76  return self;
77 }
78 
79 static VALUE
81 {
82  HMAC_CTX *ctx1, *ctx2;
83 
84  rb_check_frozen(self);
85  if (self == other) return self;
86 
87  GetHMAC(self, ctx1);
88  SafeGetHMAC(other, ctx2);
89 
90  HMAC_CTX_copy(ctx1, ctx2);
91  return self;
92 }
93 
94 /*
95  * call-seq:
96  * hmac.update(string) -> self
97  *
98  */
99 static VALUE
101 {
102  HMAC_CTX *ctx;
103 
104  StringValue(data);
105  GetHMAC(self, ctx);
106  HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));
107 
108  return self;
109 }
110 
111 static void
112 hmac_final(HMAC_CTX *ctx, unsigned char **buf, unsigned int *buf_len)
113 {
114  HMAC_CTX final;
115 
116  HMAC_CTX_copy(&final, ctx);
117  if (!(*buf = OPENSSL_malloc(HMAC_size(&final)))) {
118  HMAC_CTX_cleanup(&final);
119  OSSL_Debug("Allocating %d mem", HMAC_size(&final));
120  ossl_raise(eHMACError, "Cannot allocate memory for hmac");
121  }
122  HMAC_Final(&final, *buf, buf_len);
123  HMAC_CTX_cleanup(&final);
124 }
125 
126 /*
127  * call-seq:
128  * hmac.digest -> aString
129  *
130  */
131 static VALUE
133 {
134  HMAC_CTX *ctx;
135  unsigned char *buf;
136  unsigned int buf_len;
137  VALUE digest;
138 
139  GetHMAC(self, ctx);
140  hmac_final(ctx, &buf, &buf_len);
141  digest = ossl_buf2str((char *)buf, buf_len);
142 
143  return digest;
144 }
145 
146 /*
147  * call-seq:
148  * hmac.hexdigest -> aString
149  *
150  */
151 static VALUE
153 {
154  HMAC_CTX *ctx;
155  unsigned char *buf;
156  char *hexbuf;
157  unsigned int buf_len;
158  VALUE hexdigest;
159 
160  GetHMAC(self, ctx);
161  hmac_final(ctx, &buf, &buf_len);
162  if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * (int)buf_len) {
163  OPENSSL_free(buf);
164  ossl_raise(eHMACError, "Memory alloc error");
165  }
166  OPENSSL_free(buf);
167  hexdigest = ossl_buf2str(hexbuf, 2 * buf_len);
168 
169  return hexdigest;
170 }
171 
172 /*
173  * call-seq:
174  * hmac.reset -> self
175  *
176  */
177 static VALUE
179 {
180  HMAC_CTX *ctx;
181 
182  GetHMAC(self, ctx);
183  HMAC_Init(ctx, NULL, 0, NULL);
184 
185  return self;
186 }
187 
188 /*
189  * call-seq:
190  * HMAC.digest(digest, key, data) -> aString
191  *
192  */
193 static VALUE
195 {
196  unsigned char *buf;
197  unsigned int buf_len;
198 
199  StringValue(key);
200  StringValue(data);
201  buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key),
202  (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);
203 
204  return rb_str_new((const char *)buf, buf_len);
205 }
206 
207 /*
208  * call-seq:
209  * HMAC.digest(digest, key, data) -> aString
210  *
211  */
212 static VALUE
214 {
215  unsigned char *buf;
216  char *hexbuf;
217  unsigned int buf_len;
218  VALUE hexdigest;
219 
220  StringValue(key);
221  StringValue(data);
222 
223  buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key),
224  (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);
225  if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * (int)buf_len) {
226  ossl_raise(eHMACError, "Cannot convert buf to hexbuf");
227  }
228  hexdigest = ossl_buf2str(hexbuf, 2 * buf_len);
229 
230  return hexdigest;
231 }
232 
233 /*
234  * INIT
235  */
236 void
238 {
239 #if 0
240  mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
241 #endif
242 
244 
246 
250 
251  rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
253 
254  rb_define_method(cHMAC, "reset", ossl_hmac_reset, 0);
255  rb_define_method(cHMAC, "update", ossl_hmac_update, 1);
256  rb_define_alias(cHMAC, "<<", "update");
257  rb_define_method(cHMAC, "digest", ossl_hmac_digest, 0);
258  rb_define_method(cHMAC, "hexdigest", ossl_hmac_hexdigest, 0);
259  rb_define_alias(cHMAC, "inspect", "hexdigest");
260  rb_define_alias(cHMAC, "to_s", "hexdigest");
261 }
262 
263 #else /* NO_HMAC */
264 # warning >>> OpenSSL is compiled without HMAC support <<<
265 void
267 {
268  rb_warning("HMAC will NOT be avaible: OpenSSL is compiled without HMAC.");
269 }
270 #endif /* NO_HMAC */
VALUE data
Definition: tcltklib.c:3367
#define GetHMAC(obj, ctx)
Definition: ossl_hmac.c:17
VALUE mOSSL
Definition: ossl.c:259
VALUE cHMAC
Definition: ossl_hmac.c:31
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1501
#define rb_check_frozen(obj)
static void ossl_hmac_free(HMAC_CTX *ctx)
Definition: ossl_hmac.c:42
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
static VALUE ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
Definition: ossl_hmac.c:67
#define MakeHMAC(obj, klass, ctx)
Definition: ossl_hmac.c:15
#define RSTRING_PTR(str)
void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:549
void Init_ossl_hmac()
Definition: ossl_hmac.c:237
VALUE eHMACError
Definition: ossl_hmac.c:32
#define rb_define_copy_func(klass, func)
Definition: ruby_missing.h:14
static VALUE ossl_hmac_digest(VALUE self)
Definition: ossl_hmac.c:132
const EVP_MD * GetDigestPtr(VALUE obj)
Definition: ossl_digest.c:36
static VALUE VALUE obj
Definition: tcltklib.c:3157
#define RSTRING_LEN(str)
VALUE eOSSLError
Definition: ossl.c:264
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
static VALUE ossl_hmac_alloc(VALUE klass)
Definition: ossl_hmac.c:49
static int VALUE key
Definition: tkutil.c:265
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1543
#define StringValue(v)
#define SafeGetHMAC(obj, ctx)
Definition: ossl_hmac.c:23
void ruby_xfree(void *x)
Definition: gc.c:3653
static VALUE ossl_hmac_hexdigest(VALUE self)
Definition: ossl_hmac.c:152
#define OSSL_Debug
Definition: ossl.h:211
void HMAC_CTX_init(HMAC_CTX *ctx)
static VALUE ossl_hmac_update(VALUE self, VALUE data)
Definition: ossl_hmac.c:100
static VALUE ossl_hmac_copy(VALUE self, VALUE other)
Definition: ossl_hmac.c:80
static VALUE ossl_hmac_reset(VALUE self)
Definition: ossl_hmac.c:178
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
VALUE ossl_buf2str(char *buf, int len)
Definition: ossl.c:134
klass
Definition: tcltklib.c:3503
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:333
static VALUE ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
Definition: ossl_hmac.c:194
static void hmac_final(HMAC_CTX *ctx, unsigned char **buf, unsigned int *buf_len)
Definition: ossl_hmac.c:112
#define RSTRING_LENINT(str)
VALUE rb_str_new(const char *, long)
Definition: string.c:425
unsigned long VALUE
Definition: ripper.y:104
void rb_warning(const char *fmt,...)
Definition: error.c:234
VALUE rb_define_module(const char *name)
Definition: class.c:621
#define NULL
Definition: _sdbm.c:103
static VALUE ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)
Definition: ossl_hmac.c:213
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1348
void HMAC_CTX_cleanup(HMAC_CTX *ctx)
int string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
Definition: ossl.c:18