openssl 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -78,7 +78,7 @@ static const rb_data_type_t ossl_engine_type = {
78
78
  {
79
79
  0, ossl_engine_free,
80
80
  },
81
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
81
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
82
82
  };
83
83
 
84
84
  /*
@@ -42,7 +42,7 @@ static const rb_data_type_t ossl_hmac_type = {
42
42
  {
43
43
  0, ossl_hmac_free,
44
44
  },
45
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
45
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
46
46
  };
47
47
 
48
48
  static VALUE
@@ -21,7 +21,7 @@ static VALUE mKDF, eKDF;
21
21
  * (https://tools.ietf.org/html/rfc2898#section-5.2).
22
22
  *
23
23
  * === Parameters
24
- * pass :: The passphrase.
24
+ * pass :: The password.
25
25
  * salt :: The salt. Salts prevent attacks based on dictionaries of common
26
26
  * passwords and attacks based on rainbow tables. It is a public
27
27
  * value that can be safely stored along with the password (e.g.
@@ -50,7 +50,7 @@ static const rb_data_type_t ossl_netscape_spki_type = {
50
50
  {
51
51
  0, ossl_netscape_spki_free,
52
52
  },
53
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
53
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
54
54
  };
55
55
 
56
56
  static VALUE
@@ -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
  /*
@@ -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
@@ -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);
@@ -216,9 +216,20 @@ 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)
@@ -244,10 +255,14 @@ 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)
@@ -211,16 +211,58 @@ ossl_dsa_is_private(VALUE self)
211
211
  * dsa.to_pem([cipher, password]) -> aString
212
212
  * dsa.to_s([cipher, password]) -> aString
213
213
  *
214
- * Encodes this DSA to its PEM encoding.
214
+ * Serializes a private or public key to a PEM-encoding.
215
215
  *
216
- * === Parameters
217
- * * _cipher_ is an OpenSSL::Cipher.
218
- * * _password_ is a string containing your password.
216
+ * [When the key contains public components only]
219
217
  *
220
- * === Examples
221
- * DSA.to_pem -> aString
222
- * DSA.to_pem(cipher, 'mypassword') -> aString
218
+ * Serializes it into an X.509 SubjectPublicKeyInfo.
219
+ * The parameters _cipher_ and _password_ are ignored.
223
220
  *
221
+ * A PEM-encoded key will look like:
222
+ *
223
+ * -----BEGIN PUBLIC KEY-----
224
+ * [...]
225
+ * -----END PUBLIC KEY-----
226
+ *
227
+ * Consider using #public_to_pem instead. This serializes the key into an
228
+ * X.509 SubjectPublicKeyInfo regardless of whether it is a public key
229
+ * or a private key.
230
+ *
231
+ * [When the key contains private components, and no parameters are given]
232
+ *
233
+ * Serializes it into a traditional \OpenSSL DSAPrivateKey.
234
+ *
235
+ * A PEM-encoded key will look like:
236
+ *
237
+ * -----BEGIN DSA PRIVATE KEY-----
238
+ * [...]
239
+ * -----END DSA PRIVATE KEY-----
240
+ *
241
+ * [When the key contains private components, and _cipher_ and _password_ are given]
242
+ *
243
+ * Serializes it into a traditional \OpenSSL DSAPrivateKey and encrypts it in
244
+ * OpenSSL's traditional PEM encryption format.
245
+ * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an
246
+ * instance of OpenSSL::Cipher.
247
+ *
248
+ * An encrypted PEM-encoded key will look like:
249
+ *
250
+ * -----BEGIN DSA PRIVATE KEY-----
251
+ * Proc-Type: 4,ENCRYPTED
252
+ * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0
253
+ *
254
+ * [...]
255
+ * -----END DSA PRIVATE KEY-----
256
+ *
257
+ * Note that this format uses MD5 to derive the encryption key, and hence
258
+ * will not be available on FIPS-compliant systems.
259
+ *
260
+ * <b>This method is kept for compatibility.</b>
261
+ * This should only be used when the traditional, non-standard \OpenSSL format
262
+ * is required.
263
+ *
264
+ * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem
265
+ * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead.
224
266
  */
225
267
  static VALUE
226
268
  ossl_dsa_export(int argc, VALUE *argv, VALUE self)
@@ -238,8 +280,15 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
238
280
  * call-seq:
239
281
  * dsa.to_der -> aString
240
282
  *
241
- * Encodes this DSA to its DER encoding.
283
+ * Serializes a private or public key to a DER-encoding.
284
+ *
285
+ * See #to_pem for details.
286
+ *
287
+ * <b>This method is kept for compatibility.</b>
288
+ * This should only be used when the traditional, non-standard \OpenSSL format
289
+ * is required.
242
290
  *
291
+ * Consider using #public_to_der or #private_to_der instead.
243
292
  */
244
293
  static VALUE
245
294
  ossl_dsa_to_der(VALUE self)