rubysl-openssl 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +5 -6
- data/ext/rubysl/openssl/.gitignore +3 -0
- data/ext/rubysl/openssl/deprecation.rb +21 -0
- data/ext/rubysl/openssl/extconf.rb +45 -32
- data/ext/rubysl/openssl/openssl_missing.c +20 -7
- data/ext/rubysl/openssl/openssl_missing.h +22 -15
- data/ext/rubysl/openssl/ossl.c +610 -61
- data/ext/rubysl/openssl/ossl.h +31 -17
- data/ext/rubysl/openssl/ossl_asn1.c +974 -183
- data/ext/rubysl/openssl/ossl_asn1.h +3 -3
- data/ext/rubysl/openssl/ossl_bio.c +4 -3
- data/ext/rubysl/openssl/ossl_bio.h +1 -1
- data/ext/rubysl/openssl/ossl_bn.c +32 -28
- data/ext/rubysl/openssl/ossl_bn.h +1 -1
- data/ext/rubysl/openssl/ossl_cipher.c +494 -93
- data/ext/rubysl/openssl/ossl_cipher.h +1 -1
- data/ext/rubysl/openssl/ossl_config.c +4 -5
- data/ext/rubysl/openssl/ossl_config.h +1 -1
- data/ext/rubysl/openssl/ossl_digest.c +206 -24
- data/ext/rubysl/openssl/ossl_digest.h +1 -1
- data/ext/rubysl/openssl/ossl_engine.c +48 -26
- data/ext/rubysl/openssl/ossl_engine.h +1 -1
- data/ext/rubysl/openssl/ossl_hmac.c +40 -38
- data/ext/rubysl/openssl/ossl_hmac.h +1 -1
- data/ext/rubysl/openssl/ossl_ns_spki.c +157 -25
- data/ext/rubysl/openssl/ossl_ns_spki.h +1 -1
- data/ext/rubysl/openssl/ossl_ocsp.c +57 -40
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +15 -13
- data/ext/rubysl/openssl/ossl_pkcs12.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs5.c +108 -18
- data/ext/rubysl/openssl/ossl_pkcs7.c +44 -37
- data/ext/rubysl/openssl/ossl_pkcs7.h +1 -1
- data/ext/rubysl/openssl/ossl_pkey.c +211 -15
- data/ext/rubysl/openssl/ossl_pkey.h +19 -9
- data/ext/rubysl/openssl/ossl_pkey_dh.c +180 -47
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +184 -47
- data/ext/rubysl/openssl/ossl_pkey_ec.c +177 -93
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +209 -102
- data/ext/rubysl/openssl/ossl_rand.c +15 -15
- data/ext/rubysl/openssl/ossl_rand.h +1 -1
- data/ext/rubysl/openssl/ossl_ssl.c +939 -192
- data/ext/rubysl/openssl/ossl_ssl.h +6 -6
- data/ext/rubysl/openssl/ossl_ssl_session.c +78 -62
- data/ext/rubysl/openssl/ossl_version.h +2 -2
- data/ext/rubysl/openssl/ossl_x509.c +1 -1
- data/ext/rubysl/openssl/ossl_x509.h +1 -1
- data/ext/rubysl/openssl/ossl_x509attr.c +20 -19
- data/ext/rubysl/openssl/ossl_x509cert.c +169 -67
- data/ext/rubysl/openssl/ossl_x509crl.c +41 -39
- data/ext/rubysl/openssl/ossl_x509ext.c +51 -38
- data/ext/rubysl/openssl/ossl_x509name.c +139 -29
- data/ext/rubysl/openssl/ossl_x509req.c +42 -40
- data/ext/rubysl/openssl/ossl_x509revoked.c +20 -20
- data/ext/rubysl/openssl/ossl_x509store.c +99 -47
- data/ext/rubysl/openssl/ruby_missing.h +3 -16
- data/lib/openssl/bn.rb +19 -19
- data/lib/openssl/buffering.rb +222 -14
- data/lib/openssl/cipher.rb +20 -20
- data/lib/openssl/config.rb +1 -4
- data/lib/openssl/digest.rb +47 -19
- data/lib/openssl/ssl.rb +197 -1
- data/lib/openssl/x509.rb +162 -1
- data/lib/rubysl/openssl.rb +4 -8
- data/lib/rubysl/openssl/version.rb +1 -1
- data/rubysl-openssl.gemspec +1 -2
- metadata +16 -34
- data/ext/rubysl/openssl/extconf.h +0 -50
- data/lib/openssl/net/ftptls.rb +0 -53
- data/lib/openssl/net/telnets.rb +0 -251
- data/lib/openssl/pkcs7.rb +0 -25
- data/lib/openssl/ssl-internal.rb +0 -187
- data/lib/openssl/x509-internal.rb +0 -153
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* $Id
|
2
|
+
* $Id$
|
3
3
|
* 'OpenSSL for Ruby' project
|
4
4
|
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
5
5
|
* All rights reserved.
|
@@ -11,64 +11,64 @@
|
|
11
11
|
#include "ossl.h"
|
12
12
|
|
13
13
|
#define WrapPKCS7(klass, obj, pkcs7) do { \
|
14
|
-
if (!pkcs7) { \
|
14
|
+
if (!(pkcs7)) { \
|
15
15
|
ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
|
16
16
|
} \
|
17
|
-
obj = Data_Wrap_Struct(klass, 0, PKCS7_free, pkcs7); \
|
17
|
+
(obj) = Data_Wrap_Struct((klass), 0, PKCS7_free, (pkcs7)); \
|
18
18
|
} while (0)
|
19
19
|
#define GetPKCS7(obj, pkcs7) do { \
|
20
|
-
Data_Get_Struct(obj, PKCS7, pkcs7); \
|
21
|
-
if (!pkcs7) { \
|
20
|
+
Data_Get_Struct((obj), PKCS7, (pkcs7)); \
|
21
|
+
if (!(pkcs7)) { \
|
22
22
|
ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
|
23
23
|
} \
|
24
24
|
} while (0)
|
25
25
|
#define SafeGetPKCS7(obj, pkcs7) do { \
|
26
|
-
OSSL_Check_Kind(obj, cPKCS7); \
|
27
|
-
GetPKCS7(obj, pkcs7); \
|
26
|
+
OSSL_Check_Kind((obj), cPKCS7); \
|
27
|
+
GetPKCS7((obj), (pkcs7)); \
|
28
28
|
} while (0)
|
29
29
|
|
30
30
|
#define WrapPKCS7si(klass, obj, p7si) do { \
|
31
|
-
if (!p7si) { \
|
31
|
+
if (!(p7si)) { \
|
32
32
|
ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \
|
33
33
|
} \
|
34
|
-
obj = Data_Wrap_Struct(klass, 0, PKCS7_SIGNER_INFO_free, p7si); \
|
34
|
+
(obj) = Data_Wrap_Struct((klass), 0, PKCS7_SIGNER_INFO_free, (p7si)); \
|
35
35
|
} while (0)
|
36
36
|
#define GetPKCS7si(obj, p7si) do { \
|
37
|
-
Data_Get_Struct(obj, PKCS7_SIGNER_INFO, p7si); \
|
38
|
-
if (!p7si) { \
|
37
|
+
Data_Get_Struct((obj), PKCS7_SIGNER_INFO, (p7si)); \
|
38
|
+
if (!(p7si)) { \
|
39
39
|
ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \
|
40
40
|
} \
|
41
41
|
} while (0)
|
42
42
|
#define SafeGetPKCS7si(obj, p7si) do { \
|
43
|
-
OSSL_Check_Kind(obj, cPKCS7Signer); \
|
44
|
-
GetPKCS7si(obj, p7si); \
|
43
|
+
OSSL_Check_Kind((obj), cPKCS7Signer); \
|
44
|
+
GetPKCS7si((obj), (p7si)); \
|
45
45
|
} while (0)
|
46
46
|
|
47
47
|
#define WrapPKCS7ri(klass, obj, p7ri) do { \
|
48
|
-
if (!p7ri) { \
|
48
|
+
if (!(p7ri)) { \
|
49
49
|
ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \
|
50
50
|
} \
|
51
|
-
obj = Data_Wrap_Struct(klass, 0, PKCS7_RECIP_INFO_free, p7ri); \
|
51
|
+
(obj) = Data_Wrap_Struct((klass), 0, PKCS7_RECIP_INFO_free, (p7ri)); \
|
52
52
|
} while (0)
|
53
53
|
#define GetPKCS7ri(obj, p7ri) do { \
|
54
|
-
Data_Get_Struct(obj, PKCS7_RECIP_INFO, p7ri); \
|
55
|
-
if (!p7ri) { \
|
54
|
+
Data_Get_Struct((obj), PKCS7_RECIP_INFO, (p7ri)); \
|
55
|
+
if (!(p7ri)) { \
|
56
56
|
ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \
|
57
57
|
} \
|
58
58
|
} while (0)
|
59
59
|
#define SafeGetPKCS7ri(obj, p7ri) do { \
|
60
|
-
OSSL_Check_Kind(obj, cPKCS7Recipient); \
|
61
|
-
GetPKCS7ri(obj, p7ri); \
|
60
|
+
OSSL_Check_Kind((obj), cPKCS7Recipient); \
|
61
|
+
GetPKCS7ri((obj), (p7ri)); \
|
62
62
|
} while (0)
|
63
63
|
|
64
|
-
#define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
|
64
|
+
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
|
65
65
|
|
66
66
|
#define ossl_pkcs7_set_data(o,v) rb_iv_set((o), "@data", (v))
|
67
67
|
#define ossl_pkcs7_get_data(o) rb_iv_get((o), "@data")
|
68
68
|
#define ossl_pkcs7_set_err_string(o,v) rb_iv_set((o), "@error_string", (v))
|
69
69
|
#define ossl_pkcs7_get_err_string(o) rb_iv_get((o), "@error_string")
|
70
70
|
|
71
|
-
/*
|
71
|
+
/*
|
72
72
|
* Classes
|
73
73
|
*/
|
74
74
|
VALUE cPKCS7;
|
@@ -97,7 +97,7 @@ static PKCS7_SIGNER_INFO *
|
|
97
97
|
DupPKCS7SignerPtr(VALUE obj)
|
98
98
|
{
|
99
99
|
PKCS7_SIGNER_INFO *p7si, *pkcs7;
|
100
|
-
|
100
|
+
|
101
101
|
SafeGetPKCS7si(obj, p7si);
|
102
102
|
if (!(pkcs7 = PKCS7_SIGNER_INFO_dup(p7si))) {
|
103
103
|
ossl_raise(ePKCS7Error, NULL);
|
@@ -123,7 +123,7 @@ static PKCS7_RECIP_INFO *
|
|
123
123
|
DupPKCS7RecipientPtr(VALUE obj)
|
124
124
|
{
|
125
125
|
PKCS7_RECIP_INFO *p7ri, *pkcs7;
|
126
|
-
|
126
|
+
|
127
127
|
SafeGetPKCS7ri(obj, p7ri);
|
128
128
|
if (!(pkcs7 = PKCS7_RECIP_INFO_dup(p7ri))) {
|
129
129
|
ossl_raise(ePKCS7Error, NULL);
|
@@ -295,7 +295,7 @@ ossl_pkcs7_alloc(VALUE klass)
|
|
295
295
|
ossl_raise(ePKCS7Error, NULL);
|
296
296
|
}
|
297
297
|
WrapPKCS7(klass, obj, pkcs7);
|
298
|
-
|
298
|
+
|
299
299
|
return obj;
|
300
300
|
}
|
301
301
|
|
@@ -309,7 +309,7 @@ ossl_pkcs7_alloc(VALUE klass)
|
|
309
309
|
static VALUE
|
310
310
|
ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
|
311
311
|
{
|
312
|
-
PKCS7 *p7;
|
312
|
+
PKCS7 *p7, *pkcs = DATA_PTR(self);
|
313
313
|
BIO *in;
|
314
314
|
VALUE arg;
|
315
315
|
|
@@ -317,11 +317,18 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
|
|
317
317
|
return self;
|
318
318
|
arg = ossl_to_der_if_possible(arg);
|
319
319
|
in = ossl_obj2bio(arg);
|
320
|
-
p7 = PEM_read_bio_PKCS7(in,
|
320
|
+
p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL);
|
321
321
|
if (!p7) {
|
322
|
-
|
323
|
-
p7 = d2i_PKCS7_bio(in,
|
322
|
+
OSSL_BIO_reset(in);
|
323
|
+
p7 = d2i_PKCS7_bio(in, &pkcs);
|
324
|
+
if (!p7) {
|
325
|
+
BIO_free(in);
|
326
|
+
PKCS7_free(pkcs);
|
327
|
+
DATA_PTR(self) = NULL;
|
328
|
+
ossl_raise(rb_eArgError, "Could not parse the PKCS7");
|
329
|
+
}
|
324
330
|
}
|
331
|
+
DATA_PTR(self) = pkcs;
|
325
332
|
BIO_free(in);
|
326
333
|
ossl_pkcs7_set_data(self, Qnil);
|
327
334
|
ossl_pkcs7_set_err_string(self, Qnil);
|
@@ -493,7 +500,7 @@ ossl_pkcs7_get_signer(VALUE self)
|
|
493
500
|
PKCS7_SIGNER_INFO *si;
|
494
501
|
int num, i;
|
495
502
|
VALUE ary;
|
496
|
-
|
503
|
+
|
497
504
|
GetPKCS7(self, pkcs7);
|
498
505
|
if (!(sk = PKCS7_get_signer_info(pkcs7))) {
|
499
506
|
OSSL_Debug("OpenSSL::PKCS7#get_signer_info == NULL!");
|
@@ -535,7 +542,7 @@ ossl_pkcs7_get_recipient(VALUE self)
|
|
535
542
|
PKCS7_RECIP_INFO *si;
|
536
543
|
int num, i;
|
537
544
|
VALUE ary;
|
538
|
-
|
545
|
+
|
539
546
|
GetPKCS7(self, pkcs7);
|
540
547
|
if (PKCS7_type_is_enveloped(pkcs7))
|
541
548
|
sk = pkcs7->d.enveloped->recipientinfo;
|
@@ -775,7 +782,7 @@ ossl_pkcs7_add_data(VALUE self, VALUE data)
|
|
775
782
|
}
|
776
783
|
if(!PKCS7_dataFinal(pkcs7, out)) goto err;
|
777
784
|
ossl_pkcs7_set_data(self, Qnil);
|
778
|
-
|
785
|
+
|
779
786
|
err:
|
780
787
|
BIO_free(out);
|
781
788
|
BIO_free(in);
|
@@ -798,7 +805,7 @@ ossl_pkcs7_to_der(VALUE self)
|
|
798
805
|
if((len = i2d_PKCS7(pkcs7, NULL)) <= 0)
|
799
806
|
ossl_raise(ePKCS7Error, NULL);
|
800
807
|
str = rb_str_new(0, len);
|
801
|
-
p = RSTRING_PTR(str);
|
808
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
802
809
|
if(i2d_PKCS7(pkcs7, &p) <= 0)
|
803
810
|
ossl_raise(ePKCS7Error, NULL);
|
804
811
|
ossl_str_adjust(str, p);
|
@@ -812,7 +819,7 @@ ossl_pkcs7_to_pem(VALUE self)
|
|
812
819
|
PKCS7 *pkcs7;
|
813
820
|
BIO *out;
|
814
821
|
VALUE str;
|
815
|
-
|
822
|
+
|
816
823
|
GetPKCS7(self, pkcs7);
|
817
824
|
if (!(out = BIO_new(BIO_s_mem()))) {
|
818
825
|
ossl_raise(ePKCS7Error, NULL);
|
@@ -887,9 +894,9 @@ ossl_pkcs7si_get_signed_time(VALUE self)
|
|
887
894
|
{
|
888
895
|
PKCS7_SIGNER_INFO *p7si;
|
889
896
|
ASN1_TYPE *asn1obj;
|
890
|
-
|
897
|
+
|
891
898
|
GetPKCS7si(self, p7si);
|
892
|
-
|
899
|
+
|
893
900
|
if (!(asn1obj = PKCS7_get_signed_attribute(p7si, NID_pkcs9_signingTime))) {
|
894
901
|
ossl_raise(ePKCS7Error, NULL);
|
895
902
|
}
|
@@ -1019,10 +1026,10 @@ Init_ossl_pkcs7()
|
|
1019
1026
|
|
1020
1027
|
cPKCS7Recipient = rb_define_class_under(cPKCS7,"RecipientInfo",rb_cObject);
|
1021
1028
|
rb_define_alloc_func(cPKCS7Recipient, ossl_pkcs7ri_alloc);
|
1022
|
-
rb_define_method(cPKCS7Recipient, "initialize", ossl_pkcs7ri_initialize,1);
|
1029
|
+
rb_define_method(cPKCS7Recipient, "initialize", ossl_pkcs7ri_initialize,1);
|
1023
1030
|
rb_define_method(cPKCS7Recipient, "issuer", ossl_pkcs7ri_get_issuer,0);
|
1024
1031
|
rb_define_method(cPKCS7Recipient, "serial", ossl_pkcs7ri_get_serial,0);
|
1025
|
-
rb_define_method(cPKCS7Recipient, "enc_key", ossl_pkcs7ri_get_enc_key,0);
|
1032
|
+
rb_define_method(cPKCS7Recipient, "enc_key", ossl_pkcs7ri_get_enc_key,0);
|
1026
1033
|
|
1027
1034
|
#define DefPKCS7Const(x) rb_define_const(cPKCS7, #x, INT2NUM(PKCS7_##x))
|
1028
1035
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* $Id
|
2
|
+
* $Id$
|
3
3
|
* 'OpenSSL for Ruby' project
|
4
4
|
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
5
5
|
* All rights reserved.
|
@@ -33,6 +33,42 @@ ossl_generate_cb(int p, int n, void *arg)
|
|
33
33
|
rb_yield(ary);
|
34
34
|
}
|
35
35
|
|
36
|
+
#if HAVE_BN_GENCB
|
37
|
+
/* OpenSSL 2nd version of GN generation callback */
|
38
|
+
int
|
39
|
+
ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
|
40
|
+
{
|
41
|
+
VALUE ary;
|
42
|
+
struct ossl_generate_cb_arg *arg;
|
43
|
+
int state;
|
44
|
+
|
45
|
+
arg = (struct ossl_generate_cb_arg *)cb->arg;
|
46
|
+
if (arg->yield) {
|
47
|
+
ary = rb_ary_new2(2);
|
48
|
+
rb_ary_store(ary, 0, INT2NUM(p));
|
49
|
+
rb_ary_store(ary, 1, INT2NUM(n));
|
50
|
+
|
51
|
+
/*
|
52
|
+
* can be break by raising exception or 'break'
|
53
|
+
*/
|
54
|
+
rb_protect(rb_yield, ary, &state);
|
55
|
+
if (state) {
|
56
|
+
arg->stop = 1;
|
57
|
+
arg->state = state;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
if (arg->stop) return 0;
|
61
|
+
return 1;
|
62
|
+
}
|
63
|
+
|
64
|
+
void
|
65
|
+
ossl_generate_cb_stop(void *ptr)
|
66
|
+
{
|
67
|
+
struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr;
|
68
|
+
arg->stop = 1;
|
69
|
+
}
|
70
|
+
#endif
|
71
|
+
|
36
72
|
/*
|
37
73
|
* Public
|
38
74
|
*/
|
@@ -62,7 +98,8 @@ ossl_pkey_new(EVP_PKEY *pkey)
|
|
62
98
|
default:
|
63
99
|
ossl_raise(ePKeyError, "unsupported key type");
|
64
100
|
}
|
65
|
-
|
101
|
+
|
102
|
+
UNREACHABLE;
|
66
103
|
}
|
67
104
|
|
68
105
|
VALUE
|
@@ -75,6 +112,7 @@ ossl_pkey_new_from_file(VALUE filename)
|
|
75
112
|
if (!(fp = fopen(RSTRING_PTR(filename), "r"))) {
|
76
113
|
ossl_raise(ePKeyError, "%s", strerror(errno));
|
77
114
|
}
|
115
|
+
rb_update_max_fd(fileno(fp));
|
78
116
|
|
79
117
|
pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL);
|
80
118
|
fclose(fp);
|
@@ -85,6 +123,53 @@ ossl_pkey_new_from_file(VALUE filename)
|
|
85
123
|
return ossl_pkey_new(pkey);
|
86
124
|
}
|
87
125
|
|
126
|
+
/*
|
127
|
+
* call-seq:
|
128
|
+
* OpenSSL::PKey.read(string [, pwd ] ) -> PKey
|
129
|
+
* OpenSSL::PKey.read(file [, pwd ]) -> PKey
|
130
|
+
*
|
131
|
+
* === Parameters
|
132
|
+
* * +string+ is a DER- or PEM-encoded string containing an arbitrary private
|
133
|
+
* or public key.
|
134
|
+
* * +file+ is an instance of +File+ containing a DER- or PEM-encoded
|
135
|
+
* arbitrary private or public key.
|
136
|
+
* * +pwd+ is an optional password in case +string+ or +file+ is an encrypted
|
137
|
+
* PEM resource.
|
138
|
+
*/
|
139
|
+
static VALUE
|
140
|
+
ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
|
141
|
+
{
|
142
|
+
EVP_PKEY *pkey;
|
143
|
+
BIO *bio;
|
144
|
+
VALUE data, pass;
|
145
|
+
char *passwd = NULL;
|
146
|
+
|
147
|
+
rb_scan_args(argc, argv, "11", &data, &pass);
|
148
|
+
|
149
|
+
bio = ossl_obj2bio(data);
|
150
|
+
if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
|
151
|
+
OSSL_BIO_reset(bio);
|
152
|
+
if (!NIL_P(pass)) {
|
153
|
+
passwd = StringValuePtr(pass);
|
154
|
+
}
|
155
|
+
if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) {
|
156
|
+
OSSL_BIO_reset(bio);
|
157
|
+
if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
|
158
|
+
OSSL_BIO_reset(bio);
|
159
|
+
if (!NIL_P(pass)) {
|
160
|
+
passwd = StringValuePtr(pass);
|
161
|
+
}
|
162
|
+
pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd);
|
163
|
+
}
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
BIO_free(bio);
|
168
|
+
if (!pkey)
|
169
|
+
ossl_raise(rb_eArgError, "Could not parse PKey");
|
170
|
+
return ossl_pkey_new(pkey);
|
171
|
+
}
|
172
|
+
|
88
173
|
EVP_PKEY *
|
89
174
|
GetPKeyPtr(VALUE obj)
|
90
175
|
{
|
@@ -99,7 +184,7 @@ EVP_PKEY *
|
|
99
184
|
GetPrivPKeyPtr(VALUE obj)
|
100
185
|
{
|
101
186
|
EVP_PKEY *pkey;
|
102
|
-
|
187
|
+
|
103
188
|
if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) {
|
104
189
|
ossl_raise(rb_eArgError, "Private key is needed.");
|
105
190
|
}
|
@@ -112,7 +197,7 @@ EVP_PKEY *
|
|
112
197
|
DupPKeyPtr(VALUE obj)
|
113
198
|
{
|
114
199
|
EVP_PKEY *pkey;
|
115
|
-
|
200
|
+
|
116
201
|
SafeGetPKey(obj, pkey);
|
117
202
|
CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
118
203
|
|
@@ -123,7 +208,7 @@ EVP_PKEY *
|
|
123
208
|
DupPrivPKeyPtr(VALUE obj)
|
124
209
|
{
|
125
210
|
EVP_PKEY *pkey;
|
126
|
-
|
211
|
+
|
127
212
|
if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) {
|
128
213
|
ossl_raise(rb_eArgError, "Private key is needed.");
|
129
214
|
}
|
@@ -150,6 +235,13 @@ ossl_pkey_alloc(VALUE klass)
|
|
150
235
|
return obj;
|
151
236
|
}
|
152
237
|
|
238
|
+
/*
|
239
|
+
* call-seq:
|
240
|
+
* PKeyClass.new -> self
|
241
|
+
*
|
242
|
+
* Because PKey is an abstract class, actually calling this method explicitly
|
243
|
+
* will raise a +NotImplementedError+.
|
244
|
+
*/
|
153
245
|
static VALUE
|
154
246
|
ossl_pkey_initialize(VALUE self)
|
155
247
|
{
|
@@ -159,12 +251,29 @@ ossl_pkey_initialize(VALUE self)
|
|
159
251
|
return self;
|
160
252
|
}
|
161
253
|
|
254
|
+
/*
|
255
|
+
* call-seq:
|
256
|
+
* pkey.sign(digest, data) -> String
|
257
|
+
*
|
258
|
+
* To sign the +String+ +data+, +digest+, an instance of OpenSSL::Digest, must
|
259
|
+
* be provided. The return value is again a +String+ containing the signature.
|
260
|
+
* A PKeyError is raised should errors occur.
|
261
|
+
* Any previous state of the +Digest+ instance is irrelevant to the signature
|
262
|
+
* outcome, the digest instance is reset to its initial state during the
|
263
|
+
* operation.
|
264
|
+
*
|
265
|
+
* == Example
|
266
|
+
* data = 'Sign me!'
|
267
|
+
* digest = OpenSSL::Digest::SHA256.new
|
268
|
+
* pkey = OpenSSL::PKey::RSA.new(2048)
|
269
|
+
* signature = pkey.sign(digest, data)
|
270
|
+
*/
|
162
271
|
static VALUE
|
163
272
|
ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
|
164
273
|
{
|
165
274
|
EVP_PKEY *pkey;
|
166
275
|
EVP_MD_CTX ctx;
|
167
|
-
int buf_len;
|
276
|
+
unsigned int buf_len;
|
168
277
|
VALUE str;
|
169
278
|
|
170
279
|
if (rb_funcall(self, id_private_q, 0, NULL) != Qtrue) {
|
@@ -175,7 +284,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
|
|
175
284
|
StringValue(data);
|
176
285
|
EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
|
177
286
|
str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
|
178
|
-
if (!EVP_SignFinal(&ctx, RSTRING_PTR(str), &buf_len, pkey))
|
287
|
+
if (!EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey))
|
179
288
|
ossl_raise(ePKeyError, NULL);
|
180
289
|
assert((long)buf_len <= RSTRING_LEN(str));
|
181
290
|
rb_str_set_len(str, buf_len);
|
@@ -183,6 +292,27 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
|
|
183
292
|
return str;
|
184
293
|
}
|
185
294
|
|
295
|
+
/*
|
296
|
+
* call-seq:
|
297
|
+
* pkey.verify(digest, signature, data) -> String
|
298
|
+
*
|
299
|
+
* To verify the +String+ +signature+, +digest+, an instance of
|
300
|
+
* OpenSSL::Digest, must be provided to re-compute the message digest of the
|
301
|
+
* original +data+, also a +String+. The return value is +true+ if the
|
302
|
+
* signature is valid, +false+ otherwise. A PKeyError is raised should errors
|
303
|
+
* occur.
|
304
|
+
* Any previous state of the +Digest+ instance is irrelevant to the validation
|
305
|
+
* outcome, the digest instance is reset to its initial state during the
|
306
|
+
* operation.
|
307
|
+
*
|
308
|
+
* == Example
|
309
|
+
* data = 'Sign me!'
|
310
|
+
* digest = OpenSSL::Digest::SHA256.new
|
311
|
+
* pkey = OpenSSL::PKey::RSA.new(2048)
|
312
|
+
* signature = pkey.sign(digest, data)
|
313
|
+
* pub_key = pkey.public_key
|
314
|
+
* puts pub_key.verify(digest, signature, data) # => true
|
315
|
+
*/
|
186
316
|
static VALUE
|
187
317
|
ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
|
188
318
|
{
|
@@ -194,7 +324,7 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
|
|
194
324
|
StringValue(sig);
|
195
325
|
StringValue(data);
|
196
326
|
EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
|
197
|
-
switch (EVP_VerifyFinal(&ctx, RSTRING_PTR(sig),
|
327
|
+
switch (EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey)) {
|
198
328
|
case 0:
|
199
329
|
return Qfalse;
|
200
330
|
case 1:
|
@@ -211,24 +341,90 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
|
|
211
341
|
void
|
212
342
|
Init_ossl_pkey()
|
213
343
|
{
|
214
|
-
#if 0
|
215
|
-
mOSSL = rb_define_module("OpenSSL");
|
344
|
+
#if 0
|
345
|
+
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
|
216
346
|
#endif
|
217
|
-
|
347
|
+
|
348
|
+
/* Document-module: OpenSSL::PKey
|
349
|
+
*
|
350
|
+
* == Asymmetric Public Key Algorithms
|
351
|
+
*
|
352
|
+
* Asymmetric public key algorithms solve the problem of establishing and
|
353
|
+
* sharing secret keys to en-/decrypt messages. The key in such an
|
354
|
+
* algorithm consists of two parts: a public key that may be distributed
|
355
|
+
* to others and a private key that needs to remain secret.
|
356
|
+
*
|
357
|
+
* Messages encrypted with a public key can only be encrypted by
|
358
|
+
* recipients that are in possession of the associated private key.
|
359
|
+
* Since public key algorithms are considerably slower than symmetric
|
360
|
+
* key algorithms (cf. OpenSSL::Cipher) they are often used to establish
|
361
|
+
* a symmetric key shared between two parties that are in possession of
|
362
|
+
* each other's public key.
|
363
|
+
*
|
364
|
+
* Asymmetric algorithms offer a lot of nice features that are used in a
|
365
|
+
* lot of different areas. A very common application is the creation and
|
366
|
+
* validation of digital signatures. To sign a document, the signatory
|
367
|
+
* generally uses a message digest algorithm (cf. OpenSSL::Digest) to
|
368
|
+
* compute a digest of the document that is then encrypted (i.e. signed)
|
369
|
+
* using the private key. Anyone in possession of the public key may then
|
370
|
+
* verify the signature by computing the message digest of the original
|
371
|
+
* document on their own, decrypting the signature using the signatory's
|
372
|
+
* public key and comparing the result to the message digest they
|
373
|
+
* previously computed. The signature is valid if and only if the
|
374
|
+
* decrypted signature is equal to this message digest.
|
375
|
+
*
|
376
|
+
* The PKey module offers support for three popular public/private key
|
377
|
+
* algorithms:
|
378
|
+
* * RSA (OpenSSL::PKey::RSA)
|
379
|
+
* * DSA (OpenSSL::PKey::DSA)
|
380
|
+
* * Elliptic Curve Cryptography (OpenSSL::PKey::EC)
|
381
|
+
* Each of these implementations is in fact a sub-class of the abstract
|
382
|
+
* PKey class which offers the interface for supporting digital signatures
|
383
|
+
* in the form of PKey#sign and PKey#verify.
|
384
|
+
*
|
385
|
+
* == Diffie-Hellman Key Exchange
|
386
|
+
*
|
387
|
+
* Finally PKey also features OpenSSL::PKey::DH, an implementation of
|
388
|
+
* the Diffie-Hellman key exchange protocol based on discrete logarithms
|
389
|
+
* in finite fields, the same basis that DSA is built on.
|
390
|
+
* The Diffie-Hellman protocol can be used to exchange (symmetric) keys
|
391
|
+
* over insecure channels without needing any prior joint knowledge
|
392
|
+
* between the participating parties. As the security of DH demands
|
393
|
+
* relatively long "public keys" (i.e. the part that is overtly
|
394
|
+
* transmitted between participants) DH tends to be quite slow. If
|
395
|
+
* security or speed is your primary concern, OpenSSL::PKey::EC offers
|
396
|
+
* another implementation of the Diffie-Hellman protocol.
|
397
|
+
*
|
398
|
+
*/
|
218
399
|
mPKey = rb_define_module_under(mOSSL, "PKey");
|
219
|
-
|
400
|
+
|
401
|
+
/* Document-class: OpenSSL::PKey::PKeyError
|
402
|
+
*
|
403
|
+
*Raised when errors occur during PKey#sign or PKey#verify.
|
404
|
+
*/
|
220
405
|
ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
|
221
406
|
|
407
|
+
/* Document-class: OpenSSL::PKey::PKey
|
408
|
+
*
|
409
|
+
* An abstract class that bundles signature creation (PKey#sign) and
|
410
|
+
* validation (PKey#verify) that is common to all implementations except
|
411
|
+
* OpenSSL::PKey::DH
|
412
|
+
* * OpenSSL::PKey::RSA
|
413
|
+
* * OpenSSL::PKey::DSA
|
414
|
+
* * OpenSSL::PKey::EC
|
415
|
+
*/
|
222
416
|
cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
|
223
|
-
|
417
|
+
|
418
|
+
rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
|
419
|
+
|
224
420
|
rb_define_alloc_func(cPKey, ossl_pkey_alloc);
|
225
421
|
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
|
226
422
|
|
227
423
|
rb_define_method(cPKey, "sign", ossl_pkey_sign, 2);
|
228
424
|
rb_define_method(cPKey, "verify", ossl_pkey_verify, 3);
|
229
|
-
|
425
|
+
|
230
426
|
id_private_q = rb_intern("private?");
|
231
|
-
|
427
|
+
|
232
428
|
/*
|
233
429
|
* INIT rsa, dsa, dh, ec
|
234
430
|
*/
|