openssl 2.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openssl might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/BSDL +22 -0
- data/CONTRIBUTING.md +130 -0
- data/History.md +118 -0
- data/LICENSE.txt +56 -0
- data/README.md +70 -0
- data/ext/openssl/deprecation.rb +26 -0
- data/ext/openssl/extconf.rb +158 -0
- data/ext/openssl/openssl_missing.c +173 -0
- data/ext/openssl/openssl_missing.h +244 -0
- data/ext/openssl/ossl.c +1201 -0
- data/ext/openssl/ossl.h +222 -0
- data/ext/openssl/ossl_asn1.c +1992 -0
- data/ext/openssl/ossl_asn1.h +66 -0
- data/ext/openssl/ossl_bio.c +87 -0
- data/ext/openssl/ossl_bio.h +19 -0
- data/ext/openssl/ossl_bn.c +1153 -0
- data/ext/openssl/ossl_bn.h +23 -0
- data/ext/openssl/ossl_cipher.c +1085 -0
- data/ext/openssl/ossl_cipher.h +20 -0
- data/ext/openssl/ossl_config.c +89 -0
- data/ext/openssl/ossl_config.h +19 -0
- data/ext/openssl/ossl_digest.c +453 -0
- data/ext/openssl/ossl_digest.h +20 -0
- data/ext/openssl/ossl_engine.c +580 -0
- data/ext/openssl/ossl_engine.h +19 -0
- data/ext/openssl/ossl_hmac.c +398 -0
- data/ext/openssl/ossl_hmac.h +18 -0
- data/ext/openssl/ossl_ns_spki.c +406 -0
- data/ext/openssl/ossl_ns_spki.h +19 -0
- data/ext/openssl/ossl_ocsp.c +2013 -0
- data/ext/openssl/ossl_ocsp.h +23 -0
- data/ext/openssl/ossl_pkcs12.c +259 -0
- data/ext/openssl/ossl_pkcs12.h +13 -0
- data/ext/openssl/ossl_pkcs5.c +180 -0
- data/ext/openssl/ossl_pkcs5.h +6 -0
- data/ext/openssl/ossl_pkcs7.c +1125 -0
- data/ext/openssl/ossl_pkcs7.h +20 -0
- data/ext/openssl/ossl_pkey.c +435 -0
- data/ext/openssl/ossl_pkey.h +245 -0
- data/ext/openssl/ossl_pkey_dh.c +650 -0
- data/ext/openssl/ossl_pkey_dsa.c +672 -0
- data/ext/openssl/ossl_pkey_ec.c +1899 -0
- data/ext/openssl/ossl_pkey_rsa.c +768 -0
- data/ext/openssl/ossl_rand.c +238 -0
- data/ext/openssl/ossl_rand.h +18 -0
- data/ext/openssl/ossl_ssl.c +2679 -0
- data/ext/openssl/ossl_ssl.h +41 -0
- data/ext/openssl/ossl_ssl_session.c +352 -0
- data/ext/openssl/ossl_version.h +15 -0
- data/ext/openssl/ossl_x509.c +186 -0
- data/ext/openssl/ossl_x509.h +119 -0
- data/ext/openssl/ossl_x509attr.c +328 -0
- data/ext/openssl/ossl_x509cert.c +860 -0
- data/ext/openssl/ossl_x509crl.c +565 -0
- data/ext/openssl/ossl_x509ext.c +480 -0
- data/ext/openssl/ossl_x509name.c +547 -0
- data/ext/openssl/ossl_x509req.c +492 -0
- data/ext/openssl/ossl_x509revoked.c +279 -0
- data/ext/openssl/ossl_x509store.c +846 -0
- data/ext/openssl/ruby_missing.h +32 -0
- data/lib/openssl.rb +21 -0
- data/lib/openssl/bn.rb +39 -0
- data/lib/openssl/buffering.rb +451 -0
- data/lib/openssl/cipher.rb +67 -0
- data/lib/openssl/config.rb +473 -0
- data/lib/openssl/digest.rb +78 -0
- data/lib/openssl/pkey.rb +44 -0
- data/lib/openssl/ssl.rb +416 -0
- data/lib/openssl/x509.rb +176 -0
- metadata +178 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
/*
|
2
|
+
* 'OpenSSL for Ruby' project
|
3
|
+
* Copyright (C) 2003 Michal Rokos <m.rokos@sh.cvut.cz>
|
4
|
+
* Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
5
|
+
* All rights reserved.
|
6
|
+
*/
|
7
|
+
/*
|
8
|
+
* This program is licensed under the same licence as Ruby.
|
9
|
+
* (See the file 'LICENCE'.)
|
10
|
+
*/
|
11
|
+
#if !defined(OSSL_ENGINE_H)
|
12
|
+
#define OSSL_ENGINE_H
|
13
|
+
|
14
|
+
extern VALUE cEngine;
|
15
|
+
extern VALUE eEngineError;
|
16
|
+
|
17
|
+
void Init_ossl_engine(void);
|
18
|
+
|
19
|
+
#endif /* OSSL_ENGINE_H */
|
@@ -0,0 +1,398 @@
|
|
1
|
+
/*
|
2
|
+
* 'OpenSSL for Ruby' project
|
3
|
+
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
4
|
+
* All rights reserved.
|
5
|
+
*/
|
6
|
+
/*
|
7
|
+
* This program is licensed under the same licence as Ruby.
|
8
|
+
* (See the file 'LICENCE'.)
|
9
|
+
*/
|
10
|
+
#if !defined(OPENSSL_NO_HMAC)
|
11
|
+
|
12
|
+
#include "ossl.h"
|
13
|
+
|
14
|
+
#define NewHMAC(klass) \
|
15
|
+
TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0)
|
16
|
+
#define GetHMAC(obj, ctx) do { \
|
17
|
+
TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \
|
18
|
+
if (!(ctx)) { \
|
19
|
+
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
|
20
|
+
} \
|
21
|
+
} while (0)
|
22
|
+
#define SafeGetHMAC(obj, ctx) do { \
|
23
|
+
OSSL_Check_Kind((obj), cHMAC); \
|
24
|
+
GetHMAC((obj), (ctx)); \
|
25
|
+
} while (0)
|
26
|
+
|
27
|
+
/*
|
28
|
+
* Classes
|
29
|
+
*/
|
30
|
+
VALUE cHMAC;
|
31
|
+
VALUE eHMACError;
|
32
|
+
|
33
|
+
/*
|
34
|
+
* Public
|
35
|
+
*/
|
36
|
+
|
37
|
+
/*
|
38
|
+
* Private
|
39
|
+
*/
|
40
|
+
static void
|
41
|
+
ossl_hmac_free(void *ctx)
|
42
|
+
{
|
43
|
+
HMAC_CTX_free(ctx);
|
44
|
+
}
|
45
|
+
|
46
|
+
static const rb_data_type_t ossl_hmac_type = {
|
47
|
+
"OpenSSL/HMAC",
|
48
|
+
{
|
49
|
+
0, ossl_hmac_free,
|
50
|
+
},
|
51
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
52
|
+
};
|
53
|
+
|
54
|
+
static VALUE
|
55
|
+
ossl_hmac_alloc(VALUE klass)
|
56
|
+
{
|
57
|
+
VALUE obj;
|
58
|
+
HMAC_CTX *ctx;
|
59
|
+
|
60
|
+
obj = NewHMAC(klass);
|
61
|
+
ctx = HMAC_CTX_new();
|
62
|
+
if (!ctx)
|
63
|
+
ossl_raise(eHMACError, NULL);
|
64
|
+
RTYPEDDATA_DATA(obj) = ctx;
|
65
|
+
|
66
|
+
return obj;
|
67
|
+
}
|
68
|
+
|
69
|
+
|
70
|
+
/*
|
71
|
+
* call-seq:
|
72
|
+
* HMAC.new(key, digest) -> hmac
|
73
|
+
*
|
74
|
+
* Returns an instance of OpenSSL::HMAC set with the key and digest
|
75
|
+
* algorithm to be used. The instance represents the initial state of
|
76
|
+
* the message authentication code before any data has been processed.
|
77
|
+
* To process data with it, use the instance method #update with your
|
78
|
+
* data as an argument.
|
79
|
+
*
|
80
|
+
* === Example
|
81
|
+
*
|
82
|
+
* key = 'key'
|
83
|
+
* digest = OpenSSL::Digest.new('sha1')
|
84
|
+
* instance = OpenSSL::HMAC.new(key, digest)
|
85
|
+
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
86
|
+
* instance.class
|
87
|
+
* #=> OpenSSL::HMAC
|
88
|
+
*
|
89
|
+
* === A note about comparisons
|
90
|
+
*
|
91
|
+
* Two instances won't be equal when they're compared, even if they have the
|
92
|
+
* same value. Use #to_s or #hexdigest to return the authentication code that
|
93
|
+
* the instance represents. For example:
|
94
|
+
*
|
95
|
+
* other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
|
96
|
+
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
97
|
+
* instance
|
98
|
+
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
99
|
+
* instance == other_instance
|
100
|
+
* #=> false
|
101
|
+
* instance.to_s == other_instance.to_s
|
102
|
+
* #=> true
|
103
|
+
*
|
104
|
+
*/
|
105
|
+
static VALUE
|
106
|
+
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
107
|
+
{
|
108
|
+
HMAC_CTX *ctx;
|
109
|
+
|
110
|
+
StringValue(key);
|
111
|
+
GetHMAC(self, ctx);
|
112
|
+
HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
|
113
|
+
GetDigestPtr(digest), NULL);
|
114
|
+
|
115
|
+
return self;
|
116
|
+
}
|
117
|
+
|
118
|
+
static VALUE
|
119
|
+
ossl_hmac_copy(VALUE self, VALUE other)
|
120
|
+
{
|
121
|
+
HMAC_CTX *ctx1, *ctx2;
|
122
|
+
|
123
|
+
rb_check_frozen(self);
|
124
|
+
if (self == other) return self;
|
125
|
+
|
126
|
+
GetHMAC(self, ctx1);
|
127
|
+
SafeGetHMAC(other, ctx2);
|
128
|
+
|
129
|
+
if (!HMAC_CTX_copy(ctx1, ctx2))
|
130
|
+
ossl_raise(eHMACError, "HMAC_CTX_copy");
|
131
|
+
return self;
|
132
|
+
}
|
133
|
+
|
134
|
+
/*
|
135
|
+
* call-seq:
|
136
|
+
* hmac.update(string) -> self
|
137
|
+
*
|
138
|
+
* Returns +self+ updated with the message to be authenticated.
|
139
|
+
* Can be called repeatedly with chunks of the message.
|
140
|
+
*
|
141
|
+
* === Example
|
142
|
+
*
|
143
|
+
* first_chunk = 'The quick brown fox jumps '
|
144
|
+
* second_chunk = 'over the lazy dog'
|
145
|
+
*
|
146
|
+
* instance.update(first_chunk)
|
147
|
+
* #=> 5b9a8038a65d571076d97fe783989e52278a492a
|
148
|
+
* instance.update(second_chunk)
|
149
|
+
* #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
|
150
|
+
*
|
151
|
+
*/
|
152
|
+
static VALUE
|
153
|
+
ossl_hmac_update(VALUE self, VALUE data)
|
154
|
+
{
|
155
|
+
HMAC_CTX *ctx;
|
156
|
+
|
157
|
+
StringValue(data);
|
158
|
+
GetHMAC(self, ctx);
|
159
|
+
HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));
|
160
|
+
|
161
|
+
return self;
|
162
|
+
}
|
163
|
+
|
164
|
+
static void
|
165
|
+
hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
166
|
+
{
|
167
|
+
HMAC_CTX *final;
|
168
|
+
|
169
|
+
final = HMAC_CTX_new();
|
170
|
+
if (!final)
|
171
|
+
ossl_raise(eHMACError, "HMAC_CTX_new");
|
172
|
+
|
173
|
+
if (!HMAC_CTX_copy(final, ctx)) {
|
174
|
+
HMAC_CTX_free(final);
|
175
|
+
ossl_raise(eHMACError, "HMAC_CTX_copy");
|
176
|
+
}
|
177
|
+
|
178
|
+
HMAC_Final(final, buf, buf_len);
|
179
|
+
HMAC_CTX_free(final);
|
180
|
+
}
|
181
|
+
|
182
|
+
/*
|
183
|
+
* call-seq:
|
184
|
+
* hmac.digest -> string
|
185
|
+
*
|
186
|
+
* Returns the authentication code an instance represents as a binary string.
|
187
|
+
*
|
188
|
+
* === Example
|
189
|
+
* instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
|
190
|
+
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
191
|
+
* instance.digest
|
192
|
+
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
|
193
|
+
*/
|
194
|
+
static VALUE
|
195
|
+
ossl_hmac_digest(VALUE self)
|
196
|
+
{
|
197
|
+
HMAC_CTX *ctx;
|
198
|
+
unsigned int buf_len;
|
199
|
+
VALUE ret;
|
200
|
+
|
201
|
+
GetHMAC(self, ctx);
|
202
|
+
ret = rb_str_new(NULL, EVP_MAX_MD_SIZE);
|
203
|
+
hmac_final(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len);
|
204
|
+
assert(buf_len <= EVP_MAX_MD_SIZE);
|
205
|
+
rb_str_set_len(ret, buf_len);
|
206
|
+
|
207
|
+
return ret;
|
208
|
+
}
|
209
|
+
|
210
|
+
/*
|
211
|
+
* call-seq:
|
212
|
+
* hmac.hexdigest -> string
|
213
|
+
*
|
214
|
+
* Returns the authentication code an instance represents as a hex-encoded
|
215
|
+
* string.
|
216
|
+
*/
|
217
|
+
static VALUE
|
218
|
+
ossl_hmac_hexdigest(VALUE self)
|
219
|
+
{
|
220
|
+
HMAC_CTX *ctx;
|
221
|
+
unsigned char buf[EVP_MAX_MD_SIZE];
|
222
|
+
unsigned int buf_len;
|
223
|
+
VALUE ret;
|
224
|
+
|
225
|
+
GetHMAC(self, ctx);
|
226
|
+
hmac_final(ctx, buf, &buf_len);
|
227
|
+
ret = rb_str_new(NULL, buf_len * 2);
|
228
|
+
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
229
|
+
|
230
|
+
return ret;
|
231
|
+
}
|
232
|
+
|
233
|
+
/*
|
234
|
+
* call-seq:
|
235
|
+
* hmac.reset -> self
|
236
|
+
*
|
237
|
+
* Returns +self+ as it was when it was first initialized, with all processed
|
238
|
+
* data cleared from it.
|
239
|
+
*
|
240
|
+
* === Example
|
241
|
+
*
|
242
|
+
* data = "The quick brown fox jumps over the lazy dog"
|
243
|
+
* instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
|
244
|
+
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
245
|
+
*
|
246
|
+
* instance.update(data)
|
247
|
+
* #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
|
248
|
+
* instance.reset
|
249
|
+
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
250
|
+
*
|
251
|
+
*/
|
252
|
+
static VALUE
|
253
|
+
ossl_hmac_reset(VALUE self)
|
254
|
+
{
|
255
|
+
HMAC_CTX *ctx;
|
256
|
+
|
257
|
+
GetHMAC(self, ctx);
|
258
|
+
HMAC_Init_ex(ctx, NULL, 0, NULL, NULL);
|
259
|
+
|
260
|
+
return self;
|
261
|
+
}
|
262
|
+
|
263
|
+
/*
|
264
|
+
* call-seq:
|
265
|
+
* HMAC.digest(digest, key, data) -> aString
|
266
|
+
*
|
267
|
+
* Returns the authentication code as a binary string. The +digest+ parameter
|
268
|
+
* must be an instance of OpenSSL::Digest.
|
269
|
+
*
|
270
|
+
* === Example
|
271
|
+
*
|
272
|
+
* key = 'key'
|
273
|
+
* data = 'The quick brown fox jumps over the lazy dog'
|
274
|
+
* digest = OpenSSL::Digest.new('sha1')
|
275
|
+
*
|
276
|
+
* hmac = OpenSSL::HMAC.digest(digest, key, data)
|
277
|
+
* #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
|
278
|
+
*
|
279
|
+
*/
|
280
|
+
static VALUE
|
281
|
+
ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
|
282
|
+
{
|
283
|
+
unsigned char *buf;
|
284
|
+
unsigned int buf_len;
|
285
|
+
|
286
|
+
StringValue(key);
|
287
|
+
StringValue(data);
|
288
|
+
buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key),
|
289
|
+
(unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);
|
290
|
+
|
291
|
+
return rb_str_new((const char *)buf, buf_len);
|
292
|
+
}
|
293
|
+
|
294
|
+
/*
|
295
|
+
* call-seq:
|
296
|
+
* HMAC.hexdigest(digest, key, data) -> aString
|
297
|
+
*
|
298
|
+
* Returns the authentication code as a hex-encoded string. The +digest+
|
299
|
+
* parameter must be an instance of OpenSSL::Digest.
|
300
|
+
*
|
301
|
+
* === Example
|
302
|
+
*
|
303
|
+
* key = 'key'
|
304
|
+
* data = 'The quick brown fox jumps over the lazy dog'
|
305
|
+
* digest = OpenSSL::Digest.new('sha1')
|
306
|
+
*
|
307
|
+
* hmac = OpenSSL::HMAC.hexdigest(digest, key, data)
|
308
|
+
* #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
|
309
|
+
*
|
310
|
+
*/
|
311
|
+
static VALUE
|
312
|
+
ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)
|
313
|
+
{
|
314
|
+
unsigned char buf[EVP_MAX_MD_SIZE];
|
315
|
+
unsigned int buf_len;
|
316
|
+
VALUE ret;
|
317
|
+
|
318
|
+
StringValue(key);
|
319
|
+
StringValue(data);
|
320
|
+
|
321
|
+
if (!HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key),
|
322
|
+
(unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data),
|
323
|
+
buf, &buf_len))
|
324
|
+
ossl_raise(eHMACError, "HMAC");
|
325
|
+
|
326
|
+
ret = rb_str_new(NULL, buf_len * 2);
|
327
|
+
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
328
|
+
|
329
|
+
return ret;
|
330
|
+
}
|
331
|
+
|
332
|
+
/*
|
333
|
+
* INIT
|
334
|
+
*/
|
335
|
+
void
|
336
|
+
Init_ossl_hmac(void)
|
337
|
+
{
|
338
|
+
#if 0
|
339
|
+
mOSSL = rb_define_module("OpenSSL");
|
340
|
+
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
341
|
+
#endif
|
342
|
+
|
343
|
+
/*
|
344
|
+
* Document-class: OpenSSL::HMAC
|
345
|
+
*
|
346
|
+
* OpenSSL::HMAC allows computing Hash-based Message Authentication Code
|
347
|
+
* (HMAC). It is a type of message authentication code (MAC) involving a
|
348
|
+
* hash function in combination with a key. HMAC can be used to verify the
|
349
|
+
* integrity of a message as well as the authenticity.
|
350
|
+
*
|
351
|
+
* OpenSSL::HMAC has a similar interface to OpenSSL::Digest.
|
352
|
+
*
|
353
|
+
* === HMAC-SHA256 using one-shot interface
|
354
|
+
*
|
355
|
+
* key = "key"
|
356
|
+
* data = "message-to-be-authenticated"
|
357
|
+
* mac = OpenSSL::HMAC.hexdigest("SHA256", key, data)
|
358
|
+
* #=> "cddb0db23f469c8bf072b21fd837149bd6ace9ab771cceef14c9e517cc93282e"
|
359
|
+
*
|
360
|
+
* === HMAC-SHA256 using incremental interface
|
361
|
+
*
|
362
|
+
* data1 = File.read("file1")
|
363
|
+
* data2 = File.read("file2")
|
364
|
+
* key = "key"
|
365
|
+
* digest = OpenSSL::Digest::SHA256.new
|
366
|
+
* hmac = OpenSSL::HMAC.new(key, digest)
|
367
|
+
* hmac << data1
|
368
|
+
* hmac << data2
|
369
|
+
* mac = hmac.digest
|
370
|
+
*/
|
371
|
+
eHMACError = rb_define_class_under(mOSSL, "HMACError", eOSSLError);
|
372
|
+
|
373
|
+
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
|
374
|
+
|
375
|
+
rb_define_alloc_func(cHMAC, ossl_hmac_alloc);
|
376
|
+
rb_define_singleton_method(cHMAC, "digest", ossl_hmac_s_digest, 3);
|
377
|
+
rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3);
|
378
|
+
|
379
|
+
rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
|
380
|
+
rb_define_copy_func(cHMAC, ossl_hmac_copy);
|
381
|
+
|
382
|
+
rb_define_method(cHMAC, "reset", ossl_hmac_reset, 0);
|
383
|
+
rb_define_method(cHMAC, "update", ossl_hmac_update, 1);
|
384
|
+
rb_define_alias(cHMAC, "<<", "update");
|
385
|
+
rb_define_method(cHMAC, "digest", ossl_hmac_digest, 0);
|
386
|
+
rb_define_method(cHMAC, "hexdigest", ossl_hmac_hexdigest, 0);
|
387
|
+
rb_define_alias(cHMAC, "inspect", "hexdigest");
|
388
|
+
rb_define_alias(cHMAC, "to_s", "hexdigest");
|
389
|
+
}
|
390
|
+
|
391
|
+
#else /* NO_HMAC */
|
392
|
+
# warning >>> OpenSSL is compiled without HMAC support <<<
|
393
|
+
void
|
394
|
+
Init_ossl_hmac(void)
|
395
|
+
{
|
396
|
+
rb_warning("HMAC is not available: OpenSSL is compiled without HMAC.");
|
397
|
+
}
|
398
|
+
#endif /* NO_HMAC */
|
@@ -0,0 +1,18 @@
|
|
1
|
+
/*
|
2
|
+
* 'OpenSSL for Ruby' project
|
3
|
+
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
4
|
+
* All rights reserved.
|
5
|
+
*/
|
6
|
+
/*
|
7
|
+
* This program is licensed under the same licence as Ruby.
|
8
|
+
* (See the file 'LICENCE'.)
|
9
|
+
*/
|
10
|
+
#if !defined(_OSSL_HMAC_H_)
|
11
|
+
#define _OSSL_HMAC_H_
|
12
|
+
|
13
|
+
extern VALUE cHMAC;
|
14
|
+
extern VALUE eHMACError;
|
15
|
+
|
16
|
+
void Init_ossl_hmac(void);
|
17
|
+
|
18
|
+
#endif /* _OSSL_HMAC_H_ */
|
@@ -0,0 +1,406 @@
|
|
1
|
+
/*
|
2
|
+
* 'OpenSSL for Ruby' project
|
3
|
+
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
4
|
+
* All rights reserved.
|
5
|
+
*/
|
6
|
+
/*
|
7
|
+
* This program is licensed under the same licence as Ruby.
|
8
|
+
* (See the file 'LICENCE'.)
|
9
|
+
*/
|
10
|
+
#include "ossl.h"
|
11
|
+
|
12
|
+
#define NewSPKI(klass) \
|
13
|
+
TypedData_Wrap_Struct((klass), &ossl_netscape_spki_type, 0)
|
14
|
+
#define SetSPKI(obj, spki) do { \
|
15
|
+
if (!(spki)) { \
|
16
|
+
ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \
|
17
|
+
} \
|
18
|
+
RTYPEDDATA_DATA(obj) = (spki); \
|
19
|
+
} while (0)
|
20
|
+
#define GetSPKI(obj, spki) do { \
|
21
|
+
TypedData_Get_Struct((obj), NETSCAPE_SPKI, &ossl_netscape_spki_type, (spki)); \
|
22
|
+
if (!(spki)) { \
|
23
|
+
ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \
|
24
|
+
} \
|
25
|
+
} while (0)
|
26
|
+
|
27
|
+
/*
|
28
|
+
* Classes
|
29
|
+
*/
|
30
|
+
VALUE mNetscape;
|
31
|
+
VALUE cSPKI;
|
32
|
+
VALUE eSPKIError;
|
33
|
+
|
34
|
+
/*
|
35
|
+
* Public functions
|
36
|
+
*/
|
37
|
+
|
38
|
+
/*
|
39
|
+
* Private functions
|
40
|
+
*/
|
41
|
+
|
42
|
+
static void
|
43
|
+
ossl_netscape_spki_free(void *spki)
|
44
|
+
{
|
45
|
+
NETSCAPE_SPKI_free(spki);
|
46
|
+
}
|
47
|
+
|
48
|
+
static const rb_data_type_t ossl_netscape_spki_type = {
|
49
|
+
"OpenSSL/NETSCAPE_SPKI",
|
50
|
+
{
|
51
|
+
0, ossl_netscape_spki_free,
|
52
|
+
},
|
53
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
54
|
+
};
|
55
|
+
|
56
|
+
static VALUE
|
57
|
+
ossl_spki_alloc(VALUE klass)
|
58
|
+
{
|
59
|
+
NETSCAPE_SPKI *spki;
|
60
|
+
VALUE obj;
|
61
|
+
|
62
|
+
obj = NewSPKI(klass);
|
63
|
+
if (!(spki = NETSCAPE_SPKI_new())) {
|
64
|
+
ossl_raise(eSPKIError, NULL);
|
65
|
+
}
|
66
|
+
SetSPKI(obj, spki);
|
67
|
+
|
68
|
+
return obj;
|
69
|
+
}
|
70
|
+
|
71
|
+
/*
|
72
|
+
* call-seq:
|
73
|
+
* SPKI.new([request]) => spki
|
74
|
+
*
|
75
|
+
* === Parameters
|
76
|
+
* * +request+ - optional raw request, either in PEM or DER format.
|
77
|
+
*/
|
78
|
+
static VALUE
|
79
|
+
ossl_spki_initialize(int argc, VALUE *argv, VALUE self)
|
80
|
+
{
|
81
|
+
NETSCAPE_SPKI *spki;
|
82
|
+
VALUE buffer;
|
83
|
+
const unsigned char *p;
|
84
|
+
|
85
|
+
if (rb_scan_args(argc, argv, "01", &buffer) == 0) {
|
86
|
+
return self;
|
87
|
+
}
|
88
|
+
StringValue(buffer);
|
89
|
+
if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), RSTRING_LENINT(buffer)))) {
|
90
|
+
ossl_clear_error();
|
91
|
+
p = (unsigned char *)RSTRING_PTR(buffer);
|
92
|
+
if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) {
|
93
|
+
ossl_raise(eSPKIError, NULL);
|
94
|
+
}
|
95
|
+
}
|
96
|
+
NETSCAPE_SPKI_free(DATA_PTR(self));
|
97
|
+
SetSPKI(self, spki);
|
98
|
+
|
99
|
+
return self;
|
100
|
+
}
|
101
|
+
|
102
|
+
/*
|
103
|
+
* call-seq:
|
104
|
+
* spki.to_der => DER-encoded string
|
105
|
+
*
|
106
|
+
* Returns the DER encoding of this SPKI.
|
107
|
+
*/
|
108
|
+
static VALUE
|
109
|
+
ossl_spki_to_der(VALUE self)
|
110
|
+
{
|
111
|
+
NETSCAPE_SPKI *spki;
|
112
|
+
VALUE str;
|
113
|
+
long len;
|
114
|
+
unsigned char *p;
|
115
|
+
|
116
|
+
GetSPKI(self, spki);
|
117
|
+
if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0)
|
118
|
+
ossl_raise(eX509CertError, NULL);
|
119
|
+
str = rb_str_new(0, len);
|
120
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
121
|
+
if (i2d_NETSCAPE_SPKI(spki, &p) <= 0)
|
122
|
+
ossl_raise(eX509CertError, NULL);
|
123
|
+
ossl_str_adjust(str, p);
|
124
|
+
|
125
|
+
return str;
|
126
|
+
}
|
127
|
+
|
128
|
+
/*
|
129
|
+
* call-seq:
|
130
|
+
* spki.to_pem => PEM-encoded string
|
131
|
+
*
|
132
|
+
* Returns the PEM encoding of this SPKI.
|
133
|
+
*/
|
134
|
+
static VALUE
|
135
|
+
ossl_spki_to_pem(VALUE self)
|
136
|
+
{
|
137
|
+
NETSCAPE_SPKI *spki;
|
138
|
+
char *data;
|
139
|
+
VALUE str;
|
140
|
+
|
141
|
+
GetSPKI(self, spki);
|
142
|
+
if (!(data = NETSCAPE_SPKI_b64_encode(spki))) {
|
143
|
+
ossl_raise(eSPKIError, NULL);
|
144
|
+
}
|
145
|
+
str = ossl_buf2str(data, rb_long2int(strlen(data)));
|
146
|
+
|
147
|
+
return str;
|
148
|
+
}
|
149
|
+
|
150
|
+
/*
|
151
|
+
* call-seq:
|
152
|
+
* spki.to_text => string
|
153
|
+
*
|
154
|
+
* Returns a textual representation of this SPKI, useful for debugging
|
155
|
+
* purposes.
|
156
|
+
*/
|
157
|
+
static VALUE
|
158
|
+
ossl_spki_print(VALUE self)
|
159
|
+
{
|
160
|
+
NETSCAPE_SPKI *spki;
|
161
|
+
BIO *out;
|
162
|
+
BUF_MEM *buf;
|
163
|
+
VALUE str;
|
164
|
+
|
165
|
+
GetSPKI(self, spki);
|
166
|
+
if (!(out = BIO_new(BIO_s_mem()))) {
|
167
|
+
ossl_raise(eSPKIError, NULL);
|
168
|
+
}
|
169
|
+
if (!NETSCAPE_SPKI_print(out, spki)) {
|
170
|
+
BIO_free(out);
|
171
|
+
ossl_raise(eSPKIError, NULL);
|
172
|
+
}
|
173
|
+
BIO_get_mem_ptr(out, &buf);
|
174
|
+
str = rb_str_new(buf->data, buf->length);
|
175
|
+
BIO_free(out);
|
176
|
+
|
177
|
+
return str;
|
178
|
+
}
|
179
|
+
|
180
|
+
/*
|
181
|
+
* call-seq:
|
182
|
+
* spki.public_key => pkey
|
183
|
+
*
|
184
|
+
* Returns the public key associated with the SPKI, an instance of
|
185
|
+
* OpenSSL::PKey.
|
186
|
+
*/
|
187
|
+
static VALUE
|
188
|
+
ossl_spki_get_public_key(VALUE self)
|
189
|
+
{
|
190
|
+
NETSCAPE_SPKI *spki;
|
191
|
+
EVP_PKEY *pkey;
|
192
|
+
|
193
|
+
GetSPKI(self, spki);
|
194
|
+
if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */
|
195
|
+
ossl_raise(eSPKIError, NULL);
|
196
|
+
}
|
197
|
+
|
198
|
+
return ossl_pkey_new(pkey); /* NO DUP - OK */
|
199
|
+
}
|
200
|
+
|
201
|
+
/*
|
202
|
+
* call-seq:
|
203
|
+
* spki.public_key = pub => pkey
|
204
|
+
*
|
205
|
+
* === Parameters
|
206
|
+
* * +pub+ - the public key to be set for this instance
|
207
|
+
*
|
208
|
+
* Sets the public key to be associated with the SPKI, an instance of
|
209
|
+
* OpenSSL::PKey. This should be the public key corresponding to the
|
210
|
+
* private key used for signing the SPKI.
|
211
|
+
*/
|
212
|
+
static VALUE
|
213
|
+
ossl_spki_set_public_key(VALUE self, VALUE key)
|
214
|
+
{
|
215
|
+
NETSCAPE_SPKI *spki;
|
216
|
+
|
217
|
+
GetSPKI(self, spki);
|
218
|
+
if (!NETSCAPE_SPKI_set_pubkey(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
|
219
|
+
ossl_raise(eSPKIError, NULL);
|
220
|
+
}
|
221
|
+
|
222
|
+
return key;
|
223
|
+
}
|
224
|
+
|
225
|
+
/*
|
226
|
+
* call-seq:
|
227
|
+
* spki.challenge => string
|
228
|
+
*
|
229
|
+
* Returns the challenge string associated with this SPKI.
|
230
|
+
*/
|
231
|
+
static VALUE
|
232
|
+
ossl_spki_get_challenge(VALUE self)
|
233
|
+
{
|
234
|
+
NETSCAPE_SPKI *spki;
|
235
|
+
|
236
|
+
GetSPKI(self, spki);
|
237
|
+
if (spki->spkac->challenge->length <= 0) {
|
238
|
+
OSSL_Debug("Challenge.length <= 0?");
|
239
|
+
return rb_str_new(0, 0);
|
240
|
+
}
|
241
|
+
|
242
|
+
return rb_str_new((const char *)spki->spkac->challenge->data,
|
243
|
+
spki->spkac->challenge->length);
|
244
|
+
}
|
245
|
+
|
246
|
+
/*
|
247
|
+
* call-seq:
|
248
|
+
* spki.challenge = str => string
|
249
|
+
*
|
250
|
+
* === Parameters
|
251
|
+
* * +str+ - the challenge string to be set for this instance
|
252
|
+
*
|
253
|
+
* Sets the challenge to be associated with the SPKI. May be used by the
|
254
|
+
* server, e.g. to prevent replay.
|
255
|
+
*/
|
256
|
+
static VALUE
|
257
|
+
ossl_spki_set_challenge(VALUE self, VALUE str)
|
258
|
+
{
|
259
|
+
NETSCAPE_SPKI *spki;
|
260
|
+
|
261
|
+
StringValue(str);
|
262
|
+
GetSPKI(self, spki);
|
263
|
+
if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str),
|
264
|
+
RSTRING_LENINT(str))) {
|
265
|
+
ossl_raise(eSPKIError, NULL);
|
266
|
+
}
|
267
|
+
|
268
|
+
return str;
|
269
|
+
}
|
270
|
+
|
271
|
+
/*
|
272
|
+
* call-seq:
|
273
|
+
* spki.sign(key, digest) => spki
|
274
|
+
*
|
275
|
+
* === Parameters
|
276
|
+
* * +key+ - the private key to be used for signing this instance
|
277
|
+
* * +digest+ - the digest to be used for signing this instance
|
278
|
+
*
|
279
|
+
* To sign an SPKI, the private key corresponding to the public key set
|
280
|
+
* for this instance should be used, in addition to a digest algorithm in
|
281
|
+
* the form of an OpenSSL::Digest. The private key should be an instance of
|
282
|
+
* OpenSSL::PKey.
|
283
|
+
*/
|
284
|
+
static VALUE
|
285
|
+
ossl_spki_sign(VALUE self, VALUE key, VALUE digest)
|
286
|
+
{
|
287
|
+
NETSCAPE_SPKI *spki;
|
288
|
+
EVP_PKEY *pkey;
|
289
|
+
const EVP_MD *md;
|
290
|
+
|
291
|
+
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
|
292
|
+
md = GetDigestPtr(digest);
|
293
|
+
GetSPKI(self, spki);
|
294
|
+
if (!NETSCAPE_SPKI_sign(spki, pkey, md)) {
|
295
|
+
ossl_raise(eSPKIError, NULL);
|
296
|
+
}
|
297
|
+
|
298
|
+
return self;
|
299
|
+
}
|
300
|
+
|
301
|
+
/*
|
302
|
+
* call-seq:
|
303
|
+
* spki.verify(key) => boolean
|
304
|
+
*
|
305
|
+
* === Parameters
|
306
|
+
* * +key+ - the public key to be used for verifying the SPKI signature
|
307
|
+
*
|
308
|
+
* Returns +true+ if the signature is valid, +false+ otherwise. To verify an
|
309
|
+
* SPKI, the public key contained within the SPKI should be used.
|
310
|
+
*/
|
311
|
+
static VALUE
|
312
|
+
ossl_spki_verify(VALUE self, VALUE key)
|
313
|
+
{
|
314
|
+
NETSCAPE_SPKI *spki;
|
315
|
+
|
316
|
+
GetSPKI(self, spki);
|
317
|
+
switch (NETSCAPE_SPKI_verify(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
|
318
|
+
case 0:
|
319
|
+
return Qfalse;
|
320
|
+
case 1:
|
321
|
+
return Qtrue;
|
322
|
+
default:
|
323
|
+
ossl_raise(eSPKIError, NULL);
|
324
|
+
}
|
325
|
+
return Qnil; /* dummy */
|
326
|
+
}
|
327
|
+
|
328
|
+
/* Document-class: OpenSSL::Netscape::SPKI
|
329
|
+
*
|
330
|
+
* A Simple Public Key Infrastructure implementation (pronounced "spookey").
|
331
|
+
* The structure is defined as
|
332
|
+
* PublicKeyAndChallenge ::= SEQUENCE {
|
333
|
+
* spki SubjectPublicKeyInfo,
|
334
|
+
* challenge IA5STRING
|
335
|
+
* }
|
336
|
+
*
|
337
|
+
* SignedPublicKeyAndChallenge ::= SEQUENCE {
|
338
|
+
* publicKeyAndChallenge PublicKeyAndChallenge,
|
339
|
+
* signatureAlgorithm AlgorithmIdentifier,
|
340
|
+
* signature BIT STRING
|
341
|
+
* }
|
342
|
+
* where the definitions of SubjectPublicKeyInfo and AlgorithmIdentifier can
|
343
|
+
* be found in RFC5280. SPKI is typically used in browsers for generating
|
344
|
+
* a public/private key pair and a subsequent certificate request, using
|
345
|
+
* the HTML <keygen> element.
|
346
|
+
*
|
347
|
+
* == Examples
|
348
|
+
*
|
349
|
+
* === Creating an SPKI
|
350
|
+
* key = OpenSSL::PKey::RSA.new 2048
|
351
|
+
* spki = OpenSSL::Netscape::SPKI.new
|
352
|
+
* spki.challenge = "RandomChallenge"
|
353
|
+
* spki.public_key = key.public_key
|
354
|
+
* spki.sign(key, OpenSSL::Digest::SHA256.new)
|
355
|
+
* #send a request containing this to a server generating a certificate
|
356
|
+
* === Verifiying an SPKI request
|
357
|
+
* request = #...
|
358
|
+
* spki = OpenSSL::Netscape::SPKI.new request
|
359
|
+
* unless spki.verify(spki.public_key)
|
360
|
+
* # signature is invalid
|
361
|
+
* end
|
362
|
+
* #proceed
|
363
|
+
*/
|
364
|
+
|
365
|
+
/* Document-module: OpenSSL::Netscape
|
366
|
+
*
|
367
|
+
* OpenSSL::Netscape is a namespace for SPKI (Simple Public Key
|
368
|
+
* Infrastructure) which implements Signed Public Key and Challenge.
|
369
|
+
* See {RFC 2692}[http://tools.ietf.org/html/rfc2692] and {RFC
|
370
|
+
* 2693}[http://tools.ietf.org/html/rfc2692] for details.
|
371
|
+
*/
|
372
|
+
|
373
|
+
/* Document-class: OpenSSL::Netscape::SPKIError
|
374
|
+
*
|
375
|
+
* Generic Exception class that is raised if an error occurs during an
|
376
|
+
* operation on an instance of OpenSSL::Netscape::SPKI.
|
377
|
+
*/
|
378
|
+
|
379
|
+
void
|
380
|
+
Init_ossl_ns_spki(void)
|
381
|
+
{
|
382
|
+
#if 0
|
383
|
+
mOSSL = rb_define_module("OpenSSL");
|
384
|
+
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
385
|
+
#endif
|
386
|
+
|
387
|
+
mNetscape = rb_define_module_under(mOSSL, "Netscape");
|
388
|
+
|
389
|
+
eSPKIError = rb_define_class_under(mNetscape, "SPKIError", eOSSLError);
|
390
|
+
|
391
|
+
cSPKI = rb_define_class_under(mNetscape, "SPKI", rb_cObject);
|
392
|
+
|
393
|
+
rb_define_alloc_func(cSPKI, ossl_spki_alloc);
|
394
|
+
rb_define_method(cSPKI, "initialize", ossl_spki_initialize, -1);
|
395
|
+
|
396
|
+
rb_define_method(cSPKI, "to_der", ossl_spki_to_der, 0);
|
397
|
+
rb_define_method(cSPKI, "to_pem", ossl_spki_to_pem, 0);
|
398
|
+
rb_define_alias(cSPKI, "to_s", "to_pem");
|
399
|
+
rb_define_method(cSPKI, "to_text", ossl_spki_print, 0);
|
400
|
+
rb_define_method(cSPKI, "public_key", ossl_spki_get_public_key, 0);
|
401
|
+
rb_define_method(cSPKI, "public_key=", ossl_spki_set_public_key, 1);
|
402
|
+
rb_define_method(cSPKI, "sign", ossl_spki_sign, 2);
|
403
|
+
rb_define_method(cSPKI, "verify", ossl_spki_verify, 1);
|
404
|
+
rb_define_method(cSPKI, "challenge", ossl_spki_get_challenge, 0);
|
405
|
+
rb_define_method(cSPKI, "challenge=", ossl_spki_set_challenge, 1);
|
406
|
+
}
|