Add |SSL_CTX_set_private_key_method| to parallel |SSL_set_private_key_method|

This change adds a |SSL_CTX_set_private_key_method| method that sets key_method on a SSL_CTX's cert.

It allows the private key method to be set once and inherited.

A copy of key_method (from SSL_CTX's cert to SSL's cert) is added in |ssl_cert_dup|.

Change-Id: Icb62e9055e689cfe2d5caa3a638797120634b63f
Reviewed-on: https://boringssl-review.googlesource.com/7340
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 7cc901b..be5776c 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -465,7 +465,8 @@
  * a private key operation was unfinished. The caller may retry the operation
  * when the private key operation is complete.
  *
- * See also |SSL_set_private_key_method|. */
+ * See also |SSL_set_private_key_method| and
+ * |SSL_CTX_set_private_key_method|. */
 #define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION 13
 
 /* SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success
@@ -1003,6 +1004,11 @@
 OPENSSL_EXPORT void SSL_set_private_key_method(
     SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method);
 
+/* SSL_CTX_set_private_key_method configures a custom private key on |ctx|.
+ * |key_method| must remain valid for the lifetime of |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_set_private_key_method(
+    SSL_CTX *ctx, const SSL_PRIVATE_KEY_METHOD *key_method);
+
 
 /* Cipher suites.
  *
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 28a33c9..acdc3cb 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -185,6 +185,8 @@
     }
   }
 
+  ret->key_method = cert->key_method;
+
   ret->cert_cb = cert->cert_cb;
   ret->cert_cb_arg = cert->cert_cb_arg;
 
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index 990979b..c17d2da 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -326,6 +326,11 @@
   ssl->cert->key_method = key_method;
 }
 
+void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
+                                    const SSL_PRIVATE_KEY_METHOD *key_method) {
+  ctx->cert->key_method = key_method;
+}
+
 int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
                                      size_t num_digests) {
   OPENSSL_free(ssl->cert->digest_nids);