rubysl-openssl 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
*/
|