zig_example 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/mkmf.rb +2734 -0
- data/ext/openssl/openssl_missing.c +40 -0
- data/ext/openssl/openssl_missing.h +238 -0
- data/ext/openssl/ossl.c +1295 -0
- data/ext/openssl/ossl.h +201 -0
- data/ext/openssl/ossl_asn1.c +1891 -0
- data/ext/openssl/ossl_asn1.h +62 -0
- data/ext/openssl/ossl_bio.c +42 -0
- data/ext/openssl/ossl_bio.h +16 -0
- data/ext/openssl/ossl_bn.c +1344 -0
- data/ext/openssl/ossl_bn.h +26 -0
- data/ext/openssl/ossl_cipher.c +1074 -0
- data/ext/openssl/ossl_cipher.h +20 -0
- data/ext/openssl/ossl_config.c +460 -0
- data/ext/openssl/ossl_config.h +16 -0
- data/ext/openssl/ossl_digest.c +425 -0
- data/ext/openssl/ossl_digest.h +20 -0
- data/ext/openssl/ossl_engine.c +568 -0
- data/ext/openssl/ossl_engine.h +19 -0
- data/ext/openssl/ossl_hmac.c +310 -0
- data/ext/openssl/ossl_hmac.h +18 -0
- data/ext/openssl/ossl_kdf.c +311 -0
- data/ext/openssl/ossl_kdf.h +6 -0
- data/ext/openssl/ossl_ns_spki.c +405 -0
- data/ext/openssl/ossl_ns_spki.h +19 -0
- data/ext/openssl/ossl_ocsp.c +1965 -0
- data/ext/openssl/ossl_ocsp.h +23 -0
- data/ext/openssl/ossl_pkcs12.c +275 -0
- data/ext/openssl/ossl_pkcs12.h +13 -0
- data/ext/openssl/ossl_pkcs7.c +1081 -0
- data/ext/openssl/ossl_pkcs7.h +36 -0
- data/ext/openssl/ossl_pkey.c +1624 -0
- data/ext/openssl/ossl_pkey.h +204 -0
- data/ext/openssl/ossl_pkey_dh.c +440 -0
- data/ext/openssl/ossl_pkey_dsa.c +359 -0
- data/ext/openssl/ossl_pkey_ec.c +1655 -0
- data/ext/openssl/ossl_pkey_rsa.c +579 -0
- data/ext/openssl/ossl_rand.c +200 -0
- data/ext/openssl/ossl_rand.h +18 -0
- data/ext/openssl/ossl_ssl.c +3142 -0
- data/ext/openssl/ossl_ssl.h +36 -0
- data/ext/openssl/ossl_ssl_session.c +331 -0
- data/ext/openssl/ossl_ts.c +1539 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +256 -0
- data/ext/openssl/ossl_x509.h +115 -0
- data/ext/openssl/ossl_x509attr.c +324 -0
- data/ext/openssl/ossl_x509cert.c +1002 -0
- data/ext/openssl/ossl_x509crl.c +545 -0
- data/ext/openssl/ossl_x509ext.c +490 -0
- data/ext/openssl/ossl_x509name.c +597 -0
- data/ext/openssl/ossl_x509req.c +444 -0
- data/ext/openssl/ossl_x509revoked.c +300 -0
- data/ext/openssl/ossl_x509store.c +986 -0
- data/ext/zigrb_100doors/build.zig +0 -12
- data/ext/zigrb_100doors/extconf.rb +2 -19
- data/ext/zigrb_ackermann/build.zig +0 -12
- data/ext/zigrb_ackermann/extconf.rb +2 -19
- data/ext/zigrb_lucas_lehmer/build.zig +0 -12
- data/ext/zigrb_lucas_lehmer/extconf.rb +2 -19
- data/lib/zig_example/version.rb +1 -1
- metadata +56 -2
@@ -0,0 +1,579 @@
|
|
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
|
+
#if !defined(OPENSSL_NO_RSA)
|
13
|
+
|
14
|
+
#define GetPKeyRSA(obj, pkey) do { \
|
15
|
+
GetPKey((obj), (pkey)); \
|
16
|
+
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { /* PARANOIA? */ \
|
17
|
+
ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \
|
18
|
+
} \
|
19
|
+
} while (0)
|
20
|
+
#define GetRSA(obj, rsa) do { \
|
21
|
+
EVP_PKEY *_pkey; \
|
22
|
+
GetPKeyRSA((obj), _pkey); \
|
23
|
+
(rsa) = EVP_PKEY_get0_RSA(_pkey); \
|
24
|
+
} while (0)
|
25
|
+
|
26
|
+
static inline int
|
27
|
+
RSA_HAS_PRIVATE(OSSL_3_const RSA *rsa)
|
28
|
+
{
|
29
|
+
const BIGNUM *e, *d;
|
30
|
+
|
31
|
+
RSA_get0_key(rsa, NULL, &e, &d);
|
32
|
+
return e && d;
|
33
|
+
}
|
34
|
+
|
35
|
+
static inline int
|
36
|
+
RSA_PRIVATE(VALUE obj, OSSL_3_const RSA *rsa)
|
37
|
+
{
|
38
|
+
return RSA_HAS_PRIVATE(rsa) || OSSL_PKEY_IS_PRIVATE(obj);
|
39
|
+
}
|
40
|
+
|
41
|
+
/*
|
42
|
+
* Classes
|
43
|
+
*/
|
44
|
+
VALUE cRSA;
|
45
|
+
VALUE eRSAError;
|
46
|
+
|
47
|
+
/*
|
48
|
+
* Private
|
49
|
+
*/
|
50
|
+
/*
|
51
|
+
* call-seq:
|
52
|
+
* RSA.new -> rsa
|
53
|
+
* RSA.new(encoded_key [, passphrase]) -> rsa
|
54
|
+
* RSA.new(encoded_key) { passphrase } -> rsa
|
55
|
+
* RSA.new(size [, exponent]) -> rsa
|
56
|
+
*
|
57
|
+
* Generates or loads an \RSA keypair.
|
58
|
+
*
|
59
|
+
* If called without arguments, creates a new instance with no key components
|
60
|
+
* set. They can be set individually by #set_key, #set_factors, and
|
61
|
+
* #set_crt_params.
|
62
|
+
*
|
63
|
+
* If called with a String, tries to parse as DER or PEM encoding of an \RSA key.
|
64
|
+
* Note that, if _passphrase_ is not specified but the key is encrypted with a
|
65
|
+
* passphrase, \OpenSSL will prompt for it.
|
66
|
+
* See also OpenSSL::PKey.read which can parse keys of any kinds.
|
67
|
+
*
|
68
|
+
* If called with a number, generates a new key pair. This form works as an
|
69
|
+
* alias of RSA.generate.
|
70
|
+
*
|
71
|
+
* Examples:
|
72
|
+
* OpenSSL::PKey::RSA.new 2048
|
73
|
+
* OpenSSL::PKey::RSA.new File.read 'rsa.pem'
|
74
|
+
* OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase'
|
75
|
+
*/
|
76
|
+
static VALUE
|
77
|
+
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
|
78
|
+
{
|
79
|
+
EVP_PKEY *pkey;
|
80
|
+
RSA *rsa;
|
81
|
+
BIO *in = NULL;
|
82
|
+
VALUE arg, pass;
|
83
|
+
int type;
|
84
|
+
|
85
|
+
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
86
|
+
if (pkey)
|
87
|
+
rb_raise(rb_eTypeError, "pkey already initialized");
|
88
|
+
|
89
|
+
/* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
90
|
+
rb_scan_args(argc, argv, "02", &arg, &pass);
|
91
|
+
if (argc == 0) {
|
92
|
+
rsa = RSA_new();
|
93
|
+
if (!rsa)
|
94
|
+
ossl_raise(eRSAError, "RSA_new");
|
95
|
+
goto legacy;
|
96
|
+
}
|
97
|
+
|
98
|
+
pass = ossl_pem_passwd_value(pass);
|
99
|
+
arg = ossl_to_der_if_possible(arg);
|
100
|
+
in = ossl_obj2bio(&arg);
|
101
|
+
|
102
|
+
/* First try RSAPublicKey format */
|
103
|
+
rsa = d2i_RSAPublicKey_bio(in, NULL);
|
104
|
+
if (rsa)
|
105
|
+
goto legacy;
|
106
|
+
OSSL_BIO_reset(in);
|
107
|
+
rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
|
108
|
+
if (rsa)
|
109
|
+
goto legacy;
|
110
|
+
OSSL_BIO_reset(in);
|
111
|
+
|
112
|
+
/* Use the generic routine */
|
113
|
+
pkey = ossl_pkey_read_generic(in, pass);
|
114
|
+
BIO_free(in);
|
115
|
+
if (!pkey)
|
116
|
+
ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
|
117
|
+
|
118
|
+
type = EVP_PKEY_base_id(pkey);
|
119
|
+
if (type != EVP_PKEY_RSA) {
|
120
|
+
EVP_PKEY_free(pkey);
|
121
|
+
rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
122
|
+
}
|
123
|
+
RTYPEDDATA_DATA(self) = pkey;
|
124
|
+
return self;
|
125
|
+
|
126
|
+
legacy:
|
127
|
+
BIO_free(in);
|
128
|
+
pkey = EVP_PKEY_new();
|
129
|
+
if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
|
130
|
+
EVP_PKEY_free(pkey);
|
131
|
+
RSA_free(rsa);
|
132
|
+
ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
133
|
+
}
|
134
|
+
RTYPEDDATA_DATA(self) = pkey;
|
135
|
+
return self;
|
136
|
+
}
|
137
|
+
|
138
|
+
#ifndef HAVE_EVP_PKEY_DUP
|
139
|
+
static VALUE
|
140
|
+
ossl_rsa_initialize_copy(VALUE self, VALUE other)
|
141
|
+
{
|
142
|
+
EVP_PKEY *pkey;
|
143
|
+
RSA *rsa, *rsa_new;
|
144
|
+
|
145
|
+
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
146
|
+
if (pkey)
|
147
|
+
rb_raise(rb_eTypeError, "pkey already initialized");
|
148
|
+
GetRSA(other, rsa);
|
149
|
+
|
150
|
+
rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey,
|
151
|
+
(d2i_of_void *)d2i_RSAPrivateKey,
|
152
|
+
(char *)rsa);
|
153
|
+
if (!rsa_new)
|
154
|
+
ossl_raise(eRSAError, "ASN1_dup");
|
155
|
+
|
156
|
+
pkey = EVP_PKEY_new();
|
157
|
+
if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa_new) != 1) {
|
158
|
+
RSA_free(rsa_new);
|
159
|
+
ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
160
|
+
}
|
161
|
+
RTYPEDDATA_DATA(self) = pkey;
|
162
|
+
|
163
|
+
return self;
|
164
|
+
}
|
165
|
+
#endif
|
166
|
+
|
167
|
+
/*
|
168
|
+
* call-seq:
|
169
|
+
* rsa.public? => true
|
170
|
+
*
|
171
|
+
* The return value is always +true+ since every private key is also a public
|
172
|
+
* key.
|
173
|
+
*/
|
174
|
+
static VALUE
|
175
|
+
ossl_rsa_is_public(VALUE self)
|
176
|
+
{
|
177
|
+
OSSL_3_const RSA *rsa;
|
178
|
+
|
179
|
+
GetRSA(self, rsa);
|
180
|
+
/*
|
181
|
+
* This method should check for n and e. BUG.
|
182
|
+
*/
|
183
|
+
(void)rsa;
|
184
|
+
return Qtrue;
|
185
|
+
}
|
186
|
+
|
187
|
+
/*
|
188
|
+
* call-seq:
|
189
|
+
* rsa.private? => true | false
|
190
|
+
*
|
191
|
+
* Does this keypair contain a private key?
|
192
|
+
*/
|
193
|
+
static VALUE
|
194
|
+
ossl_rsa_is_private(VALUE self)
|
195
|
+
{
|
196
|
+
OSSL_3_const RSA *rsa;
|
197
|
+
|
198
|
+
GetRSA(self, rsa);
|
199
|
+
|
200
|
+
return RSA_PRIVATE(self, rsa) ? Qtrue : Qfalse;
|
201
|
+
}
|
202
|
+
|
203
|
+
static int
|
204
|
+
can_export_rsaprivatekey(VALUE self)
|
205
|
+
{
|
206
|
+
OSSL_3_const RSA *rsa;
|
207
|
+
const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
|
208
|
+
|
209
|
+
GetRSA(self, rsa);
|
210
|
+
|
211
|
+
RSA_get0_key(rsa, &n, &e, &d);
|
212
|
+
RSA_get0_factors(rsa, &p, &q);
|
213
|
+
RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
|
214
|
+
|
215
|
+
return n && e && d && p && q && dmp1 && dmq1 && iqmp;
|
216
|
+
}
|
217
|
+
|
218
|
+
/*
|
219
|
+
* call-seq:
|
220
|
+
* rsa.export([cipher, pass_phrase]) => PEM-format String
|
221
|
+
* rsa.to_pem([cipher, pass_phrase]) => PEM-format String
|
222
|
+
* rsa.to_s([cipher, pass_phrase]) => PEM-format String
|
223
|
+
*
|
224
|
+
* Outputs this keypair in PEM encoding. If _cipher_ and _pass_phrase_ are
|
225
|
+
* given they will be used to encrypt the key. _cipher_ must be an
|
226
|
+
* OpenSSL::Cipher instance.
|
227
|
+
*/
|
228
|
+
static VALUE
|
229
|
+
ossl_rsa_export(int argc, VALUE *argv, VALUE self)
|
230
|
+
{
|
231
|
+
if (can_export_rsaprivatekey(self))
|
232
|
+
return ossl_pkey_export_traditional(argc, argv, self, 0);
|
233
|
+
else
|
234
|
+
return ossl_pkey_export_spki(self, 0);
|
235
|
+
}
|
236
|
+
|
237
|
+
/*
|
238
|
+
* call-seq:
|
239
|
+
* rsa.to_der => DER-format String
|
240
|
+
*
|
241
|
+
* Outputs this keypair in DER encoding.
|
242
|
+
*/
|
243
|
+
static VALUE
|
244
|
+
ossl_rsa_to_der(VALUE self)
|
245
|
+
{
|
246
|
+
if (can_export_rsaprivatekey(self))
|
247
|
+
return ossl_pkey_export_traditional(0, NULL, self, 1);
|
248
|
+
else
|
249
|
+
return ossl_pkey_export_spki(self, 1);
|
250
|
+
}
|
251
|
+
|
252
|
+
/*
|
253
|
+
* call-seq:
|
254
|
+
* rsa.sign_pss(digest, data, salt_length:, mgf1_hash:) -> String
|
255
|
+
*
|
256
|
+
* Signs _data_ using the Probabilistic Signature Scheme (RSA-PSS) and returns
|
257
|
+
* the calculated signature.
|
258
|
+
*
|
259
|
+
* RSAError will be raised if an error occurs.
|
260
|
+
*
|
261
|
+
* See #verify_pss for the verification operation.
|
262
|
+
*
|
263
|
+
* === Parameters
|
264
|
+
* _digest_::
|
265
|
+
* A String containing the message digest algorithm name.
|
266
|
+
* _data_::
|
267
|
+
* A String. The data to be signed.
|
268
|
+
* _salt_length_::
|
269
|
+
* The length in octets of the salt. Two special values are reserved:
|
270
|
+
* +:digest+ means the digest length, and +:max+ means the maximum possible
|
271
|
+
* length for the combination of the private key and the selected message
|
272
|
+
* digest algorithm.
|
273
|
+
* _mgf1_hash_::
|
274
|
+
* The hash algorithm used in MGF1 (the currently supported mask generation
|
275
|
+
* function (MGF)).
|
276
|
+
*
|
277
|
+
* === Example
|
278
|
+
* data = "Sign me!"
|
279
|
+
* pkey = OpenSSL::PKey::RSA.new(2048)
|
280
|
+
* signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256")
|
281
|
+
* pub_key = OpenSSL::PKey.read(pkey.public_to_der)
|
282
|
+
* puts pub_key.verify_pss("SHA256", signature, data,
|
283
|
+
* salt_length: :auto, mgf1_hash: "SHA256") # => true
|
284
|
+
*/
|
285
|
+
static VALUE
|
286
|
+
ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self)
|
287
|
+
{
|
288
|
+
VALUE digest, data, options, kwargs[2], signature;
|
289
|
+
static ID kwargs_ids[2];
|
290
|
+
EVP_PKEY *pkey;
|
291
|
+
EVP_PKEY_CTX *pkey_ctx;
|
292
|
+
const EVP_MD *md, *mgf1md;
|
293
|
+
EVP_MD_CTX *md_ctx;
|
294
|
+
size_t buf_len;
|
295
|
+
int salt_len;
|
296
|
+
|
297
|
+
if (!kwargs_ids[0]) {
|
298
|
+
kwargs_ids[0] = rb_intern_const("salt_length");
|
299
|
+
kwargs_ids[1] = rb_intern_const("mgf1_hash");
|
300
|
+
}
|
301
|
+
rb_scan_args(argc, argv, "2:", &digest, &data, &options);
|
302
|
+
rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
|
303
|
+
if (kwargs[0] == ID2SYM(rb_intern("max")))
|
304
|
+
salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */
|
305
|
+
else if (kwargs[0] == ID2SYM(rb_intern("digest")))
|
306
|
+
salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
|
307
|
+
else
|
308
|
+
salt_len = NUM2INT(kwargs[0]);
|
309
|
+
mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
|
310
|
+
|
311
|
+
pkey = GetPrivPKeyPtr(self);
|
312
|
+
buf_len = EVP_PKEY_size(pkey);
|
313
|
+
md = ossl_evp_get_digestbyname(digest);
|
314
|
+
StringValue(data);
|
315
|
+
signature = rb_str_new(NULL, (long)buf_len);
|
316
|
+
|
317
|
+
md_ctx = EVP_MD_CTX_new();
|
318
|
+
if (!md_ctx)
|
319
|
+
goto err;
|
320
|
+
|
321
|
+
if (EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
|
322
|
+
goto err;
|
323
|
+
|
324
|
+
if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
|
325
|
+
goto err;
|
326
|
+
|
327
|
+
if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
|
328
|
+
goto err;
|
329
|
+
|
330
|
+
if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
|
331
|
+
goto err;
|
332
|
+
|
333
|
+
if (EVP_DigestSignUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
|
334
|
+
goto err;
|
335
|
+
|
336
|
+
if (EVP_DigestSignFinal(md_ctx, (unsigned char *)RSTRING_PTR(signature), &buf_len) != 1)
|
337
|
+
goto err;
|
338
|
+
|
339
|
+
rb_str_set_len(signature, (long)buf_len);
|
340
|
+
|
341
|
+
EVP_MD_CTX_free(md_ctx);
|
342
|
+
return signature;
|
343
|
+
|
344
|
+
err:
|
345
|
+
EVP_MD_CTX_free(md_ctx);
|
346
|
+
ossl_raise(eRSAError, NULL);
|
347
|
+
}
|
348
|
+
|
349
|
+
/*
|
350
|
+
* call-seq:
|
351
|
+
* rsa.verify_pss(digest, signature, data, salt_length:, mgf1_hash:) -> true | false
|
352
|
+
*
|
353
|
+
* Verifies _data_ using the Probabilistic Signature Scheme (RSA-PSS).
|
354
|
+
*
|
355
|
+
* The return value is +true+ if the signature is valid, +false+ otherwise.
|
356
|
+
* RSAError will be raised if an error occurs.
|
357
|
+
*
|
358
|
+
* See #sign_pss for the signing operation and an example code.
|
359
|
+
*
|
360
|
+
* === Parameters
|
361
|
+
* _digest_::
|
362
|
+
* A String containing the message digest algorithm name.
|
363
|
+
* _data_::
|
364
|
+
* A String. The data to be signed.
|
365
|
+
* _salt_length_::
|
366
|
+
* The length in octets of the salt. Two special values are reserved:
|
367
|
+
* +:digest+ means the digest length, and +:auto+ means automatically
|
368
|
+
* determining the length based on the signature.
|
369
|
+
* _mgf1_hash_::
|
370
|
+
* The hash algorithm used in MGF1.
|
371
|
+
*/
|
372
|
+
static VALUE
|
373
|
+
ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self)
|
374
|
+
{
|
375
|
+
VALUE digest, signature, data, options, kwargs[2];
|
376
|
+
static ID kwargs_ids[2];
|
377
|
+
EVP_PKEY *pkey;
|
378
|
+
EVP_PKEY_CTX *pkey_ctx;
|
379
|
+
const EVP_MD *md, *mgf1md;
|
380
|
+
EVP_MD_CTX *md_ctx;
|
381
|
+
int result, salt_len;
|
382
|
+
|
383
|
+
if (!kwargs_ids[0]) {
|
384
|
+
kwargs_ids[0] = rb_intern_const("salt_length");
|
385
|
+
kwargs_ids[1] = rb_intern_const("mgf1_hash");
|
386
|
+
}
|
387
|
+
rb_scan_args(argc, argv, "3:", &digest, &signature, &data, &options);
|
388
|
+
rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs);
|
389
|
+
if (kwargs[0] == ID2SYM(rb_intern("auto")))
|
390
|
+
salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */
|
391
|
+
else if (kwargs[0] == ID2SYM(rb_intern("digest")))
|
392
|
+
salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */
|
393
|
+
else
|
394
|
+
salt_len = NUM2INT(kwargs[0]);
|
395
|
+
mgf1md = ossl_evp_get_digestbyname(kwargs[1]);
|
396
|
+
|
397
|
+
GetPKey(self, pkey);
|
398
|
+
md = ossl_evp_get_digestbyname(digest);
|
399
|
+
StringValue(signature);
|
400
|
+
StringValue(data);
|
401
|
+
|
402
|
+
md_ctx = EVP_MD_CTX_new();
|
403
|
+
if (!md_ctx)
|
404
|
+
goto err;
|
405
|
+
|
406
|
+
if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1)
|
407
|
+
goto err;
|
408
|
+
|
409
|
+
if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1)
|
410
|
+
goto err;
|
411
|
+
|
412
|
+
if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1)
|
413
|
+
goto err;
|
414
|
+
|
415
|
+
if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1)
|
416
|
+
goto err;
|
417
|
+
|
418
|
+
if (EVP_DigestVerifyUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
|
419
|
+
goto err;
|
420
|
+
|
421
|
+
result = EVP_DigestVerifyFinal(md_ctx,
|
422
|
+
(unsigned char *)RSTRING_PTR(signature),
|
423
|
+
RSTRING_LEN(signature));
|
424
|
+
|
425
|
+
switch (result) {
|
426
|
+
case 0:
|
427
|
+
ossl_clear_error();
|
428
|
+
EVP_MD_CTX_free(md_ctx);
|
429
|
+
return Qfalse;
|
430
|
+
case 1:
|
431
|
+
EVP_MD_CTX_free(md_ctx);
|
432
|
+
return Qtrue;
|
433
|
+
default:
|
434
|
+
goto err;
|
435
|
+
}
|
436
|
+
|
437
|
+
err:
|
438
|
+
EVP_MD_CTX_free(md_ctx);
|
439
|
+
ossl_raise(eRSAError, NULL);
|
440
|
+
}
|
441
|
+
|
442
|
+
/*
|
443
|
+
* call-seq:
|
444
|
+
* rsa.params => hash
|
445
|
+
*
|
446
|
+
* THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
|
447
|
+
*
|
448
|
+
* Stores all parameters of key to the hash. The hash has keys 'n', 'e', 'd',
|
449
|
+
* 'p', 'q', 'dmp1', 'dmq1', 'iqmp'.
|
450
|
+
*
|
451
|
+
* Don't use :-)) (It's up to you)
|
452
|
+
*/
|
453
|
+
static VALUE
|
454
|
+
ossl_rsa_get_params(VALUE self)
|
455
|
+
{
|
456
|
+
OSSL_3_const RSA *rsa;
|
457
|
+
VALUE hash;
|
458
|
+
const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
|
459
|
+
|
460
|
+
GetRSA(self, rsa);
|
461
|
+
RSA_get0_key(rsa, &n, &e, &d);
|
462
|
+
RSA_get0_factors(rsa, &p, &q);
|
463
|
+
RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
|
464
|
+
|
465
|
+
hash = rb_hash_new();
|
466
|
+
rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(n));
|
467
|
+
rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(e));
|
468
|
+
rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(d));
|
469
|
+
rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
|
470
|
+
rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
|
471
|
+
rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(dmp1));
|
472
|
+
rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(dmq1));
|
473
|
+
rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(iqmp));
|
474
|
+
|
475
|
+
return hash;
|
476
|
+
}
|
477
|
+
|
478
|
+
/*
|
479
|
+
* Document-method: OpenSSL::PKey::RSA#set_key
|
480
|
+
* call-seq:
|
481
|
+
* rsa.set_key(n, e, d) -> self
|
482
|
+
*
|
483
|
+
* Sets _n_, _e_, _d_ for the RSA instance.
|
484
|
+
*/
|
485
|
+
OSSL_PKEY_BN_DEF3(rsa, RSA, key, n, e, d)
|
486
|
+
/*
|
487
|
+
* Document-method: OpenSSL::PKey::RSA#set_factors
|
488
|
+
* call-seq:
|
489
|
+
* rsa.set_factors(p, q) -> self
|
490
|
+
*
|
491
|
+
* Sets _p_, _q_ for the RSA instance.
|
492
|
+
*/
|
493
|
+
OSSL_PKEY_BN_DEF2(rsa, RSA, factors, p, q)
|
494
|
+
/*
|
495
|
+
* Document-method: OpenSSL::PKey::RSA#set_crt_params
|
496
|
+
* call-seq:
|
497
|
+
* rsa.set_crt_params(dmp1, dmq1, iqmp) -> self
|
498
|
+
*
|
499
|
+
* Sets _dmp1_, _dmq1_, _iqmp_ for the RSA instance. They are calculated by
|
500
|
+
* <tt>d mod (p - 1)</tt>, <tt>d mod (q - 1)</tt> and <tt>q^(-1) mod p</tt>
|
501
|
+
* respectively.
|
502
|
+
*/
|
503
|
+
OSSL_PKEY_BN_DEF3(rsa, RSA, crt_params, dmp1, dmq1, iqmp)
|
504
|
+
|
505
|
+
/*
|
506
|
+
* INIT
|
507
|
+
*/
|
508
|
+
#define DefRSAConst(x) rb_define_const(cRSA, #x, INT2NUM(RSA_##x))
|
509
|
+
|
510
|
+
void
|
511
|
+
Init_ossl_rsa(void)
|
512
|
+
{
|
513
|
+
#if 0
|
514
|
+
mPKey = rb_define_module_under(mOSSL, "PKey");
|
515
|
+
cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
|
516
|
+
ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
|
517
|
+
#endif
|
518
|
+
|
519
|
+
/* Document-class: OpenSSL::PKey::RSAError
|
520
|
+
*
|
521
|
+
* Generic exception that is raised if an operation on an RSA PKey
|
522
|
+
* fails unexpectedly or in case an instantiation of an instance of RSA
|
523
|
+
* fails due to non-conformant input data.
|
524
|
+
*/
|
525
|
+
eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError);
|
526
|
+
|
527
|
+
/* Document-class: OpenSSL::PKey::RSA
|
528
|
+
*
|
529
|
+
* RSA is an asymmetric public key algorithm that has been formalized in
|
530
|
+
* RFC 3447. It is in widespread use in public key infrastructures (PKI)
|
531
|
+
* where certificates (cf. OpenSSL::X509::Certificate) often are issued
|
532
|
+
* on the basis of a public/private RSA key pair. RSA is used in a wide
|
533
|
+
* field of applications such as secure (symmetric) key exchange, e.g.
|
534
|
+
* when establishing a secure TLS/SSL connection. It is also used in
|
535
|
+
* various digital signature schemes.
|
536
|
+
*/
|
537
|
+
cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
|
538
|
+
|
539
|
+
rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
|
540
|
+
#ifndef HAVE_EVP_PKEY_DUP
|
541
|
+
rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1);
|
542
|
+
#endif
|
543
|
+
|
544
|
+
rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
|
545
|
+
rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
|
546
|
+
rb_define_method(cRSA, "export", ossl_rsa_export, -1);
|
547
|
+
rb_define_alias(cRSA, "to_pem", "export");
|
548
|
+
rb_define_alias(cRSA, "to_s", "export");
|
549
|
+
rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
|
550
|
+
rb_define_method(cRSA, "sign_pss", ossl_rsa_sign_pss, -1);
|
551
|
+
rb_define_method(cRSA, "verify_pss", ossl_rsa_verify_pss, -1);
|
552
|
+
|
553
|
+
DEF_OSSL_PKEY_BN(cRSA, rsa, n);
|
554
|
+
DEF_OSSL_PKEY_BN(cRSA, rsa, e);
|
555
|
+
DEF_OSSL_PKEY_BN(cRSA, rsa, d);
|
556
|
+
DEF_OSSL_PKEY_BN(cRSA, rsa, p);
|
557
|
+
DEF_OSSL_PKEY_BN(cRSA, rsa, q);
|
558
|
+
DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
|
559
|
+
DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
|
560
|
+
DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
|
561
|
+
rb_define_method(cRSA, "set_key", ossl_rsa_set_key, 3);
|
562
|
+
rb_define_method(cRSA, "set_factors", ossl_rsa_set_factors, 2);
|
563
|
+
rb_define_method(cRSA, "set_crt_params", ossl_rsa_set_crt_params, 3);
|
564
|
+
|
565
|
+
rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
|
566
|
+
|
567
|
+
/*
|
568
|
+
* TODO: Test it
|
569
|
+
rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0);
|
570
|
+
rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0);
|
571
|
+
*/
|
572
|
+
}
|
573
|
+
|
574
|
+
#else /* defined NO_RSA */
|
575
|
+
void
|
576
|
+
Init_ossl_rsa(void)
|
577
|
+
{
|
578
|
+
}
|
579
|
+
#endif /* NO_RSA */
|