openssl 3.0.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +1 -1
  3. data/History.md +76 -0
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +89 -55
  6. data/ext/openssl/ossl.c +73 -195
  7. data/ext/openssl/ossl.h +11 -6
  8. data/ext/openssl/ossl_asn1.c +11 -10
  9. data/ext/openssl/ossl_bn.c +25 -13
  10. data/ext/openssl/ossl_cipher.c +2 -3
  11. data/ext/openssl/ossl_config.c +1 -1
  12. data/ext/openssl/ossl_digest.c +1 -1
  13. data/ext/openssl/ossl_engine.c +1 -1
  14. data/ext/openssl/ossl_hmac.c +1 -1
  15. data/ext/openssl/ossl_kdf.c +4 -4
  16. data/ext/openssl/ossl_ns_spki.c +1 -1
  17. data/ext/openssl/ossl_ocsp.c +8 -8
  18. data/ext/openssl/ossl_pkcs12.c +1 -1
  19. data/ext/openssl/ossl_pkcs7.c +3 -3
  20. data/ext/openssl/ossl_pkey.c +219 -46
  21. data/ext/openssl/ossl_pkey.h +1 -1
  22. data/ext/openssl/ossl_pkey_dh.c +28 -13
  23. data/ext/openssl/ossl_pkey_dsa.c +64 -15
  24. data/ext/openssl/ossl_pkey_ec.c +73 -17
  25. data/ext/openssl/ossl_pkey_rsa.c +74 -19
  26. data/ext/openssl/ossl_provider.c +211 -0
  27. data/ext/openssl/ossl_provider.h +5 -0
  28. data/ext/openssl/ossl_ssl.c +292 -113
  29. data/ext/openssl/ossl_ssl_session.c +5 -1
  30. data/ext/openssl/ossl_ts.c +3 -3
  31. data/ext/openssl/ossl_x509attr.c +1 -1
  32. data/ext/openssl/ossl_x509cert.c +1 -1
  33. data/ext/openssl/ossl_x509crl.c +1 -1
  34. data/ext/openssl/ossl_x509ext.c +13 -7
  35. data/ext/openssl/ossl_x509name.c +1 -1
  36. data/ext/openssl/ossl_x509req.c +1 -1
  37. data/ext/openssl/ossl_x509revoked.c +1 -1
  38. data/ext/openssl/ossl_x509store.c +12 -5
  39. data/lib/openssl/buffering.rb +2 -5
  40. data/lib/openssl/digest.rb +1 -5
  41. data/lib/openssl/pkey.rb +8 -4
  42. data/lib/openssl/ssl.rb +15 -10
  43. data/lib/openssl/version.rb +1 -1
  44. metadata +9 -6
@@ -86,7 +86,7 @@ static const rb_data_type_t ossl_ocsp_request_type = {
86
86
  {
87
87
  0, ossl_ocsp_request_free,
88
88
  },
89
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
89
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
90
90
  };
91
91
 
92
92
  static void
@@ -100,7 +100,7 @@ static const rb_data_type_t ossl_ocsp_response_type = {
100
100
  {
101
101
  0, ossl_ocsp_response_free,
102
102
  },
103
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
103
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
104
104
  };
105
105
 
106
106
  static void
@@ -114,7 +114,7 @@ static const rb_data_type_t ossl_ocsp_basicresp_type = {
114
114
  {
115
115
  0, ossl_ocsp_basicresp_free,
116
116
  },
117
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
117
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
118
118
  };
119
119
 
120
120
  static void
@@ -128,7 +128,7 @@ static const rb_data_type_t ossl_ocsp_singleresp_type = {
128
128
  {
129
129
  0, ossl_ocsp_singleresp_free,
130
130
  },
131
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
131
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
132
132
  };
133
133
 
134
134
  static void
@@ -142,7 +142,7 @@ static const rb_data_type_t ossl_ocsp_certid_type = {
142
142
  {
143
143
  0, ossl_ocsp_certid_free,
144
144
  },
145
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
145
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
146
146
  };
147
147
 
148
148
  /*
@@ -382,7 +382,7 @@ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
382
382
  if (!NIL_P(flags))
383
383
  flg = NUM2INT(flags);
384
384
  if (NIL_P(digest))
385
- md = EVP_sha1();
385
+ md = NULL;
386
386
  else
387
387
  md = ossl_evp_get_digestbyname(digest);
388
388
  if (NIL_P(certs))
@@ -1033,7 +1033,7 @@ ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
1033
1033
  if (!NIL_P(flags))
1034
1034
  flg = NUM2INT(flags);
1035
1035
  if (NIL_P(digest))
1036
- md = EVP_sha1();
1036
+ md = NULL;
1037
1037
  else
1038
1038
  md = ossl_evp_get_digestbyname(digest);
1039
1039
  if (NIL_P(certs))
@@ -1701,7 +1701,7 @@ Init_ossl_ocsp(void)
1701
1701
  * require 'net/http'
1702
1702
  *
1703
1703
  * http_response =
1704
- * Net::HTTP.start ocsp_uri.hostname, ocsp.port do |http|
1704
+ * Net::HTTP.start ocsp_uri.hostname, ocsp_uri.port do |http|
1705
1705
  * http.post ocsp_uri.path, request.to_der,
1706
1706
  * 'content-type' => 'application/ocsp-request'
1707
1707
  * end
@@ -44,7 +44,7 @@ static const rb_data_type_t ossl_pkcs12_type = {
44
44
  {
45
45
  0, ossl_pkcs12_free,
46
46
  },
47
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
47
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
48
48
  };
49
49
 
50
50
  static VALUE
@@ -65,7 +65,7 @@ const rb_data_type_t ossl_pkcs7_type = {
65
65
  {
66
66
  0, ossl_pkcs7_free,
67
67
  },
68
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
68
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
69
69
  };
70
70
 
71
71
  static void
@@ -79,7 +79,7 @@ static const rb_data_type_t ossl_pkcs7_signer_info_type = {
79
79
  {
80
80
  0, ossl_pkcs7_signer_info_free,
81
81
  },
82
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
82
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
83
83
  };
84
84
 
85
85
  static void
@@ -93,7 +93,7 @@ static const rb_data_type_t ossl_pkcs7_recip_info_type = {
93
93
  {
94
94
  0, ossl_pkcs7_recip_info_free,
95
95
  },
96
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
96
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
97
97
  };
98
98
 
99
99
  /*
@@ -35,7 +35,7 @@ const rb_data_type_t ossl_evp_pkey_type = {
35
35
  {
36
36
  0, ossl_evp_pkey_free,
37
37
  },
38
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
38
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
39
39
  };
40
40
 
41
41
  static VALUE
@@ -82,31 +82,62 @@ ossl_pkey_new(EVP_PKEY *pkey)
82
82
  #if OSSL_OPENSSL_PREREQ(3, 0, 0)
83
83
  # include <openssl/decoder.h>
84
84
 
85
- EVP_PKEY *
86
- ossl_pkey_read_generic(BIO *bio, VALUE pass)
85
+ static EVP_PKEY *
86
+ ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass)
87
87
  {
88
88
  void *ppass = (void *)pass;
89
89
  OSSL_DECODER_CTX *dctx;
90
90
  EVP_PKEY *pkey = NULL;
91
91
  int pos = 0, pos2;
92
92
 
93
- dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, NULL, 0, NULL, NULL);
93
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, input_type, NULL, NULL,
94
+ selection, NULL, NULL);
94
95
  if (!dctx)
95
96
  goto out;
96
- if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb, ppass) != 1)
97
- goto out;
98
-
99
- /* First check DER */
100
- if (OSSL_DECODER_from_bio(dctx, bio) == 1)
97
+ if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb,
98
+ ppass) != 1)
101
99
  goto out;
100
+ while (1) {
101
+ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
102
+ goto out;
103
+ if (BIO_eof(bio))
104
+ break;
105
+ pos2 = BIO_tell(bio);
106
+ if (pos2 < 0 || pos2 <= pos)
107
+ break;
108
+ ossl_clear_error();
109
+ pos = pos2;
110
+ }
111
+ out:
102
112
  OSSL_BIO_reset(bio);
113
+ OSSL_DECODER_CTX_free(dctx);
114
+ return pkey;
115
+ }
103
116
 
104
- /* Then check PEM; multiple OSSL_DECODER_from_bio() calls may be needed */
105
- if (OSSL_DECODER_CTX_set_input_type(dctx, "PEM") != 1)
106
- goto out;
117
+ EVP_PKEY *
118
+ ossl_pkey_read_generic(BIO *bio, VALUE pass)
119
+ {
120
+ EVP_PKEY *pkey = NULL;
121
+ /* First check DER, then check PEM. */
122
+ const char *input_types[] = {"DER", "PEM"};
123
+ int input_type_num = (int)(sizeof(input_types) / sizeof(char *));
107
124
  /*
108
- * First check for private key formats. This is to keep compatibility with
109
- * ruby/openssl < 3.0 which decoded the following as a private key.
125
+ * Non-zero selections to try to decode.
126
+ *
127
+ * See EVP_PKEY_fromdata(3) - Selections to see all the selections.
128
+ *
129
+ * This is a workaround for the decoder failing to decode or returning
130
+ * bogus keys with selection 0, if a key management provider is different
131
+ * from a decoder provider. The workaround is to avoid using selection 0.
132
+ *
133
+ * Affected OpenSSL versions: >= 3.1.0, <= 3.1.2, or >= 3.0.0, <= 3.0.10
134
+ * Fixed OpenSSL versions: 3.2, next release of the 3.1.z and 3.0.z
135
+ *
136
+ * See https://github.com/openssl/openssl/pull/21519 for details.
137
+ *
138
+ * First check for private key formats (EVP_PKEY_KEYPAIR). This is to keep
139
+ * compatibility with ruby/openssl < 3.0 which decoded the following as a
140
+ * private key.
110
141
  *
111
142
  * $ openssl ecparam -name prime256v1 -genkey -outform PEM
112
143
  * -----BEGIN EC PARAMETERS-----
@@ -124,36 +155,28 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
124
155
  *
125
156
  * Note that normally, the input is supposed to contain a single decodable
126
157
  * PEM block only, so this special handling should not create a new problem.
158
+ *
159
+ * Note that we need to create the OSSL_DECODER_CTX variable each time when
160
+ * we use the different selection as a workaround.
161
+ * See https://github.com/openssl/openssl/issues/20657 for details.
127
162
  */
128
- OSSL_DECODER_CTX_set_selection(dctx, EVP_PKEY_KEYPAIR);
129
- while (1) {
130
- if (OSSL_DECODER_from_bio(dctx, bio) == 1)
131
- goto out;
132
- if (BIO_eof(bio))
133
- break;
134
- pos2 = BIO_tell(bio);
135
- if (pos2 < 0 || pos2 <= pos)
136
- break;
137
- ossl_clear_error();
138
- pos = pos2;
139
- }
140
-
141
- OSSL_BIO_reset(bio);
142
- OSSL_DECODER_CTX_set_selection(dctx, 0);
143
- while (1) {
144
- if (OSSL_DECODER_from_bio(dctx, bio) == 1)
145
- goto out;
146
- if (BIO_eof(bio))
147
- break;
148
- pos2 = BIO_tell(bio);
149
- if (pos2 < 0 || pos2 <= pos)
150
- break;
151
- ossl_clear_error();
152
- pos = pos2;
163
+ int selections[] = {
164
+ EVP_PKEY_KEYPAIR,
165
+ EVP_PKEY_KEY_PARAMETERS,
166
+ EVP_PKEY_PUBLIC_KEY
167
+ };
168
+ int selection_num = (int)(sizeof(selections) / sizeof(int));
169
+ int i, j;
170
+
171
+ for (i = 0; i < input_type_num; i++) {
172
+ for (j = 0; j < selection_num; j++) {
173
+ pkey = ossl_pkey_read(bio, input_types[i], selections[j], pass);
174
+ if (pkey) {
175
+ goto out;
176
+ }
177
+ }
153
178
  }
154
-
155
179
  out:
156
- OSSL_DECODER_CTX_free(dctx);
157
180
  return pkey;
158
181
  }
159
182
  #else
@@ -260,9 +283,9 @@ struct pkey_blocking_generate_arg {
260
283
  EVP_PKEY_CTX *ctx;
261
284
  EVP_PKEY *pkey;
262
285
  int state;
263
- int yield: 1;
264
- int genparam: 1;
265
- int interrupted: 1;
286
+ unsigned int yield: 1;
287
+ unsigned int genparam: 1;
288
+ unsigned int interrupted: 1;
266
289
  };
267
290
 
268
291
  static VALUE
@@ -612,6 +635,72 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other)
612
635
  }
613
636
  #endif
614
637
 
638
+ #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
639
+ /*
640
+ * call-seq:
641
+ * OpenSSL::PKey.new_raw_private_key(algo, string) -> PKey
642
+ *
643
+ * See the OpenSSL documentation for EVP_PKEY_new_raw_private_key()
644
+ */
645
+
646
+ static VALUE
647
+ ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key)
648
+ {
649
+ EVP_PKEY *pkey;
650
+ const EVP_PKEY_ASN1_METHOD *ameth;
651
+ int pkey_id;
652
+ size_t keylen;
653
+
654
+ StringValue(type);
655
+ StringValue(key);
656
+ ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type));
657
+ if (!ameth)
658
+ ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type);
659
+ EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
660
+
661
+ keylen = RSTRING_LEN(key);
662
+
663
+ pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
664
+ if (!pkey)
665
+ ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key");
666
+
667
+ return ossl_pkey_new(pkey);
668
+ }
669
+ #endif
670
+
671
+ #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
672
+ /*
673
+ * call-seq:
674
+ * OpenSSL::PKey.new_raw_public_key(algo, string) -> PKey
675
+ *
676
+ * See the OpenSSL documentation for EVP_PKEY_new_raw_public_key()
677
+ */
678
+
679
+ static VALUE
680
+ ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key)
681
+ {
682
+ EVP_PKEY *pkey;
683
+ const EVP_PKEY_ASN1_METHOD *ameth;
684
+ int pkey_id;
685
+ size_t keylen;
686
+
687
+ StringValue(type);
688
+ StringValue(key);
689
+ ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type));
690
+ if (!ameth)
691
+ ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type);
692
+ EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
693
+
694
+ keylen = RSTRING_LEN(key);
695
+
696
+ pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen);
697
+ if (!pkey)
698
+ ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key");
699
+
700
+ return ossl_pkey_new(pkey);
701
+ }
702
+ #endif
703
+
615
704
  /*
616
705
  * call-seq:
617
706
  * pkey.oid -> string
@@ -793,6 +882,18 @@ ossl_pkey_private_to_der(int argc, VALUE *argv, VALUE self)
793
882
  *
794
883
  * Serializes the private key to PEM-encoded PKCS #8 format. See #private_to_der
795
884
  * for more details.
885
+ *
886
+ * An unencrypted PEM-encoded key will look like:
887
+ *
888
+ * -----BEGIN PRIVATE KEY-----
889
+ * [...]
890
+ * -----END PRIVATE KEY-----
891
+ *
892
+ * An encrypted PEM-encoded key will look like:
893
+ *
894
+ * -----BEGIN ENCRYPTED PRIVATE KEY-----
895
+ * [...]
896
+ * -----END ENCRYPTED PRIVATE KEY-----
796
897
  */
797
898
  static VALUE
798
899
  ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
@@ -800,6 +901,35 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
800
901
  return do_pkcs8_export(argc, argv, self, 0);
801
902
  }
802
903
 
904
+ #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
905
+ /*
906
+ * call-seq:
907
+ * pkey.raw_private_key => string
908
+ *
909
+ * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key()
910
+ */
911
+
912
+ static VALUE
913
+ ossl_pkey_raw_private_key(VALUE self)
914
+ {
915
+ EVP_PKEY *pkey;
916
+ VALUE str;
917
+ size_t len;
918
+
919
+ GetPKey(self, pkey);
920
+ if (EVP_PKEY_get_raw_private_key(pkey, NULL, &len) != 1)
921
+ ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key");
922
+ str = rb_str_new(NULL, len);
923
+
924
+ if (EVP_PKEY_get_raw_private_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1)
925
+ ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key");
926
+
927
+ rb_str_set_len(str, len);
928
+
929
+ return str;
930
+ }
931
+ #endif
932
+
803
933
  VALUE
804
934
  ossl_pkey_export_spki(VALUE self, int to_der)
805
935
  {
@@ -842,6 +972,12 @@ ossl_pkey_public_to_der(VALUE self)
842
972
  * pkey.public_to_pem -> string
843
973
  *
844
974
  * Serializes the public key to PEM-encoded X.509 SubjectPublicKeyInfo format.
975
+ *
976
+ * A PEM-encoded key will look like:
977
+ *
978
+ * -----BEGIN PUBLIC KEY-----
979
+ * [...]
980
+ * -----END PUBLIC KEY-----
845
981
  */
846
982
  static VALUE
847
983
  ossl_pkey_public_to_pem(VALUE self)
@@ -849,6 +985,35 @@ ossl_pkey_public_to_pem(VALUE self)
849
985
  return ossl_pkey_export_spki(self, 0);
850
986
  }
851
987
 
988
+ #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
989
+ /*
990
+ * call-seq:
991
+ * pkey.raw_public_key => string
992
+ *
993
+ * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key()
994
+ */
995
+
996
+ static VALUE
997
+ ossl_pkey_raw_public_key(VALUE self)
998
+ {
999
+ EVP_PKEY *pkey;
1000
+ VALUE str;
1001
+ size_t len;
1002
+
1003
+ GetPKey(self, pkey);
1004
+ if (EVP_PKEY_get_raw_public_key(pkey, NULL, &len) != 1)
1005
+ ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key");
1006
+ str = rb_str_new(NULL, len);
1007
+
1008
+ if (EVP_PKEY_get_raw_public_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1)
1009
+ ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key");
1010
+
1011
+ rb_str_set_len(str, len);
1012
+
1013
+ return str;
1014
+ }
1015
+ #endif
1016
+
852
1017
  /*
853
1018
  * call-seq:
854
1019
  * pkey.compare?(another_pkey) -> true | false
@@ -951,7 +1116,7 @@ ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
951
1116
  rb_jump_tag(state);
952
1117
  }
953
1118
  }
954
- #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
1119
+ #if OSSL_OPENSSL_PREREQ(1, 1, 1) || OSSL_LIBRESSL_PREREQ(3, 4, 0)
955
1120
  if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data),
956
1121
  RSTRING_LEN(data)) < 1) {
957
1122
  EVP_MD_CTX_free(ctx);
@@ -1056,7 +1221,7 @@ ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
1056
1221
  rb_jump_tag(state);
1057
1222
  }
1058
1223
  }
1059
- #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
1224
+ #if OSSL_OPENSSL_PREREQ(1, 1, 1) || OSSL_LIBRESSL_PREREQ(3, 4, 0)
1060
1225
  ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig),
1061
1226
  RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data),
1062
1227
  RSTRING_LEN(data));
@@ -1586,6 +1751,10 @@ Init_ossl_pkey(void)
1586
1751
  rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
1587
1752
  rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1);
1588
1753
  rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1);
1754
+ #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
1755
+ rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_new_raw_private_key, 2);
1756
+ rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_new_raw_public_key, 2);
1757
+ #endif
1589
1758
 
1590
1759
  rb_define_alloc_func(cPKey, ossl_pkey_alloc);
1591
1760
  rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
@@ -1601,6 +1770,10 @@ Init_ossl_pkey(void)
1601
1770
  rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
1602
1771
  rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
1603
1772
  rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0);
1773
+ #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY
1774
+ rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0);
1775
+ rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0);
1776
+ #endif
1604
1777
  rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1);
1605
1778
 
1606
1779
  rb_define_method(cPKey, "sign", ossl_pkey_sign, -1);
@@ -92,7 +92,7 @@ void Init_ossl_ec(void);
92
92
  */ \
93
93
  static VALUE ossl_##_keytype##_get_##_name(VALUE self) \
94
94
  { \
95
- _type *obj; \
95
+ const _type *obj; \
96
96
  const BIGNUM *bn; \
97
97
  \
98
98
  Get##_type(self, obj); \
@@ -178,7 +178,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
178
178
  static VALUE
179
179
  ossl_dh_is_public(VALUE self)
180
180
  {
181
- DH *dh;
181
+ OSSL_3_const DH *dh;
182
182
  const BIGNUM *bn;
183
183
 
184
184
  GetDH(self, dh);
@@ -197,14 +197,14 @@ ossl_dh_is_public(VALUE self)
197
197
  static VALUE
198
198
  ossl_dh_is_private(VALUE self)
199
199
  {
200
- DH *dh;
200
+ OSSL_3_const DH *dh;
201
201
  const BIGNUM *bn;
202
202
 
203
203
  GetDH(self, dh);
204
204
  DH_get0_key(dh, NULL, &bn);
205
205
 
206
206
  #if !defined(OPENSSL_NO_ENGINE)
207
- return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse;
207
+ return (bn || DH_get0_engine((DH *)dh)) ? Qtrue : Qfalse;
208
208
  #else
209
209
  return bn ? Qtrue : Qfalse;
210
210
  #endif
@@ -216,14 +216,25 @@ ossl_dh_is_private(VALUE self)
216
216
  * dh.to_pem -> aString
217
217
  * dh.to_s -> aString
218
218
  *
219
- * Encodes this DH to its PEM encoding. Note that any existing per-session
220
- * public/private keys will *not* get encoded, just the Diffie-Hellman
221
- * parameters will be encoded.
219
+ * Serializes the DH parameters to a PEM-encoding.
220
+ *
221
+ * Note that any existing per-session public/private keys will *not* get
222
+ * encoded, just the Diffie-Hellman parameters will be encoded.
223
+ *
224
+ * PEM-encoded parameters will look like:
225
+ *
226
+ * -----BEGIN DH PARAMETERS-----
227
+ * [...]
228
+ * -----END DH PARAMETERS-----
229
+ *
230
+ * See also #public_to_pem (X.509 SubjectPublicKeyInfo) and
231
+ * #private_to_pem (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for
232
+ * serialization with the private or public key components.
222
233
  */
223
234
  static VALUE
224
235
  ossl_dh_export(VALUE self)
225
236
  {
226
- DH *dh;
237
+ OSSL_3_const DH *dh;
227
238
  BIO *out;
228
239
  VALUE str;
229
240
 
@@ -244,15 +255,19 @@ ossl_dh_export(VALUE self)
244
255
  * call-seq:
245
256
  * dh.to_der -> aString
246
257
  *
247
- * Encodes this DH to its DER encoding. Note that any existing per-session
248
- * public/private keys will *not* get encoded, just the Diffie-Hellman
249
- * parameters will be encoded.
250
-
258
+ * Serializes the DH parameters to a DER-encoding
259
+ *
260
+ * Note that any existing per-session public/private keys will *not* get
261
+ * encoded, just the Diffie-Hellman parameters will be encoded.
262
+ *
263
+ * See also #public_to_der (X.509 SubjectPublicKeyInfo) and
264
+ * #private_to_der (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for
265
+ * serialization with the private or public key components.
251
266
  */
252
267
  static VALUE
253
268
  ossl_dh_to_der(VALUE self)
254
269
  {
255
- DH *dh;
270
+ OSSL_3_const DH *dh;
256
271
  unsigned char *p;
257
272
  long len;
258
273
  VALUE str;
@@ -280,7 +295,7 @@ ossl_dh_to_der(VALUE self)
280
295
  static VALUE
281
296
  ossl_dh_get_params(VALUE self)
282
297
  {
283
- DH *dh;
298
+ OSSL_3_const DH *dh;
284
299
  VALUE hash;
285
300
  const BIGNUM *p, *q, *g, *pub_key, *priv_key;
286
301