Add a size hook to RSA_METHOD.

This is to avoid having to copy over the RSA modulus in all of Chromium's
platform-specific keys.

Change-Id: I20bf22446a5cfb633b900c3b392b7a1da81a5431
Reviewed-on: https://boringssl-review.googlesource.com/1151
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/rsa/rsa.c b/crypto/rsa/rsa.c
index 583e667..526e468 100644
--- a/crypto/rsa/rsa.c
+++ b/crypto/rsa/rsa.c
@@ -249,7 +249,11 @@
 }
 
 unsigned RSA_size(const RSA *rsa) {
-  return BN_num_bytes(rsa->n);
+  if (rsa->meth->size) {
+    return rsa->meth->size(rsa);
+  }
+
+  return RSA_default_method.size(rsa);
 }
 
 int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
index 403e833..2db0abe 100644
--- a/crypto/rsa/rsa.h
+++ b/crypto/rsa/rsa.h
@@ -328,6 +328,9 @@
   int (*init)(RSA *rsa);
   int (*finish)(RSA *rsa);
 
+  /* size returns the size of the RSA modulus in bytes. */
+  size_t (*size)(const RSA *rsa);
+
   int (*sign)(int type, const uint8_t *m, unsigned int m_length,
               uint8_t *sigret, unsigned int *siglen, const RSA *rsa);
 
diff --git a/crypto/rsa/rsa_impl.c b/crypto/rsa/rsa_impl.c
index 2a8511f..6cc8475 100644
--- a/crypto/rsa/rsa_impl.c
+++ b/crypto/rsa/rsa_impl.c
@@ -83,6 +83,10 @@
   return 1;
 }
 
+static size_t size(const RSA *rsa) {
+  return BN_num_bytes(rsa->n);
+}
+
 static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                    const uint8_t *in, size_t in_len, int padding) {
   const unsigned rsa_size = RSA_size(rsa);
@@ -992,6 +996,8 @@
   NULL /* init */,
   finish,
 
+  size,
+
   NULL /* sign */,
   NULL /* verify */,